• “蔚来杯“2022牛客暑期多校训练营5


    虽然这场题面数据idea啥的出了很多锅,但是评价题是佬们的事情,像我这种菜比就应该好好补题了。。。

    K Headphones

    一共有n对耳机,其中一人已经拿出k对,问另一人要是想拿出大于k对的耳机,至少要取多少只,耳机是蓝牙耳机,一只一只相互配对。

    思路:简单容斥原理,考虑最坏情况下最少拿多少可以凑成k+1对,即一开始拿的时候每对取了一只。

     AC Code:

    1. #include
    2. typedef long long ll;
    3. ll n,k;
    4. int main(){
    5. std::ios::sync_with_stdio(false);
    6. std::cin.tie(0);
    7. std::cout.tie(0);
    8. while(std::cin>>n>>k){
    9. if(n-k1) std::cout<<-1<<'\n';
    10. else std::cout<1<<'\n';
    11. }
    12. return 0;
    13. }

    B Watches

    给定n件物品和编号i,买k件物品每件的花费为a[i]+k*i,问给出一个钱数,最多可以买几件物品。

    思路:不难想到我们可以二分答案k,对于每个k,贪心购买k件物品,判断和给出钱数的关系,时间复杂度为O(nlogn^2),能过。

    AC Code:

    1. #include
    2. typedef long long ll;
    3. const int mod=1e9+7;
    4. const int N=1e5+5;
    5. int n,m;
    6. ll a[N];
    7. struct node{
    8. ll val;
    9. }e[N];
    10. bool cmp(node a,node b){
    11. return a.val
    12. }
    13. bool check(int mid){
    14. for(int i=1;i<=n;i++){
    15. e[i].val=a[i]+(ll)i*(ll)mid;
    16. }
    17. std::sort(e+1,e+1+n,cmp);
    18. ll sum=0;
    19. for(int i=1;i<=mid;i++){
    20. sum+=e[i].val;
    21. }
    22. if(sum>m) return true;
    23. else return false;
    24. }
    25. int main(){
    26. std::ios::sync_with_stdio(false);
    27. std::cin.tie(0);
    28. std::cout.tie(0);
    29. while(std::cin>>n>>m){
    30. for(int i=1;i<=n;i++){
    31. std::cin>>a[i];
    32. }
    33. int l=0,r=n;
    34. while(l
    35. int mid=(l+r+1)/2;
    36. if(check(mid)) r=mid-1;
    37. else l=mid;
    38. }
    39. std::cout<'\n';
    40. }
    41. return 0;
    42. }

     H Cutting Papers

    给出一个不等式和圆形的描述,计算两个图形在坐标轴上并集的面积大小。

    思路:根据不等式和圆形描述画出图形,即:

     

    计算的就是灰色部分和圆形的并集,直接按照数值计算即可。

    AC Code:

    1. #include
    2. const double PI=acos(-1);
    3. double n;
    4. int main(){
    5. while(~scanf("%lf",&n)){
    6. printf("%.9lf\n",n*n/(double)2+PI*n*n/(double)8);
    7. }
    8. return 0;
    9. }

     C Bit Transmission

    给出n*3个询问,每个询问给出关于该位是否是1的回答,所有的回答中至多有1个是错误的,问是否可以得到原来的答案,否则输出-1。

    思路:我们可以记录每一位YES和NO的个数。先看不能得到答案的情况:如果存在不被问到的位置,输出-1;如果某一位YES/NO次数相同,输出-1;如果某一位YES/NO次数均大于1,输出-1;否则,我们判断下是否存在YES和NO均出现过的位置,假设共出现x次,如果x>1,输出-1;如果x=1,表明错误位置确定,此时能够确定唯一字符串; 如果x=0,那么我们判断下是否存在YES和NO总共出现1次的位置,存在表明无法确定,否则则能够唯一确定字符串。

    AC Code:

    1. #include
    2. typedef long long ll;
    3. const int N=1e5+5;
    4. int n;
    5. int ans[N];
    6. struct node{
    7. int y,n;
    8. }e[N];
    9. int main(){
    10. std::ios::sync_with_stdio(false);
    11. std::cin.tie(0);
    12. std::cout.tie(0);
    13. std::cin>>n;
    14. for(int i=1;i<=3*n;i++){
    15. int pos;
    16. std::string s;
    17. std::cin>>pos>>s;
    18. if(s=="YES") e[pos].y++;
    19. else e[pos].n++;
    20. }
    21. int cnt=0;
    22. for(int i=0;i
    23. if(e[i].y&&e[i].n) cnt++;
    24. if(cnt>1){
    25. std::cout<<-1<<'\n';
    26. return 0;
    27. }
    28. if(e[i].y==e[i].n){
    29. std::cout<<-1<<'\n';
    30. return 0;
    31. }
    32. if(!e[i].y&&!e[i].n){
    33. std::cout<<-1<<'\n';
    34. return 0;
    35. }
    36. if(e[i].y>1&&e[i].n>1){
    37. std::cout<<-1<<'\n';
    38. return 0;
    39. }
    40. if(e[i].y>e[i].n) ans[i]=1;
    41. else ans[i]=0;
    42. }
    43. if(!cnt){
    44. bool flag=false;
    45. for(int i=0;i
    46. if(e[i].y+e[i].n==1){
    47. flag=true;
    48. }
    49. }
    50. if(flag){
    51. std::cout<<-1<<'\n';
    52. return 0;
    53. }
    54. }
    55. for(int i=0;i
    56. std::cout<
    57. }
    58. std::cout<<'\n';
    59. return 0;
    60. }

    os:实质就是一个模拟, 不过分类讨论题真的ex。

    G KFC Crazy Thursday

    输出以三个字母为结尾的回文串数目。

    思路:回文自动机(PAM)裸题,可以学习。

    AC Code:

    1. #include
    2. typedef long long ll;
    3. const int mod=1e9+7;
    4. const int N=5e5+5;
    5. int n;
    6. char str[N];
    7. struct PAM {
    8. int size,last,r0,r1;
    9. int trie[N][26],fail[N],len[N],cnt[N];
    10. PAM(){
    11. r0=size++,r1=size++;last=r1;
    12. len[r0]=0,fail[r0]=r1;
    13. len[r1]=-1,fail[r1]=r1;
    14. }
    15. void insert(int ch,int idx){
    16. int u=last;
    17. while(str[idx]!=str[idx-len[u]-1])u=fail[u];
    18. if(!trie[u][ch]){
    19. int cur=++size,v=fail[u];
    20. len[cur]=len[u]+2;
    21. for(;str[idx]!=str[idx-len[v]-1];v=fail[v]);
    22. fail[cur]=trie[v][ch];
    23. trie[u][ch]=cur;
    24. cnt[cur]=cnt[fail[cur]]+1;
    25. }
    26. last=trie[u][ch];
    27. }
    28. void build(char* str){
    29. int len=strlen(str);
    30. int K=0,C=0,F=0;
    31. for(int i=0;i
    32. insert(str[i]-'a'+1,i);
    33. if(str[i]=='k') K+=cnt[last];
    34. if(str[i]=='f') F+=cnt[last];
    35. if(str[i]=='c') C+=cnt[last];
    36. }
    37. printf("%d %d %d\n",K,F,C);
    38. }
    39. }pam;
    40. int main(){
    41. while(~scanf("%d",&n)){
    42. scanf("%s",str);
    43. pam.build(str);
    44. }
    45. return 0;
    46. }

    A Don’t Starve

    给定n个点有食物(每个点可以吃多次),每个点有一个坐标,对与行走的规则是每一步都必须严格短于上一步,问最优的方案下能够吃到多少次食物。

    思路:标解:我们考虑设立状态f[i][j]表示上一步在i,当前这步走到j了的情况下最多已经吃到次数是多少,而对于转移,因为我们知道了最近两步的行走,所以可以直接计算出上一步的长度从而进行转移了。(实际上我还是不太明白这个是怎么转移的呜呜呜)

    AC Code:

    1. #include
    2. #define int long long
    3. const int N=3e3+5;
    4. const int M=6e6+5;
    5. int n,ans,cnt;
    6. int f[N][N],tong[N];
    7. struct Point{
    8. int x,y;
    9. }e[N];
    10. struct node{
    11. int u,v,w;
    12. bool operator <(const node &a)const{
    13. return w
    14. }
    15. }edge[M];
    16. int dis(int u,int v){
    17. return (e[u].x-e[v].x)*(e[u].x-e[v].x)+(e[u].y-e[v].y)*(e[u].y-e[v].y);
    18. }
    19. signed main(){
    20. std::ios::sync_with_stdio(false);
    21. std::cin.tie(0);
    22. std::cout.tie(0);
    23. std::cin>>n;
    24. for(int i=1;i<=n;i++){
    25. std::cin>>e[i].x>>e[i].y;
    26. }
    27. for(int i=0;i<=n;i++){
    28. for(int j=1;j<=n;j++){
    29. if(i==j) continue;
    30. cnt++;
    31. edge[cnt]={i,j,dis(i,j)};
    32. }
    33. }
    34. std::sort(edge+1,edge+1+cnt);
    35. for(int i=1;i<=cnt;){
    36. int b=i,e=i;
    37. while(edge[b].w==edge[e].w){
    38. int last=edge[e].u,cur=edge[e].v;
    39. f[last][cur]=std::max(f[last][cur],tong[cur]+1);
    40. ++e;
    41. }
    42. for(int j=b;j
    43. int last=edge[j].u,cur=edge[j].v;
    44. tong[last]=std::max(tong[last],f[last][cur]);
    45. }
    46. i=e;
    47. }
    48. for(int i=1;i<=n;i++){
    49. ans=std::max(ans,f[0][i]);
    50. }
    51. std::cout<'\n';
    52. return 0;
    53. }

    直接补不动了

  • 相关阅读:
    基于springboot实现校园医疗保险管理系统【项目源码】计算机毕业设计
    c共享内存
    A股风格因子看板 (2023.09 第08期)
    如何设计缓存中间层
    java-php-net-python-文献资料管理系统计算机毕业设计程序
    Linux shell编程学习笔记59: ps 获取系统进程信息,类似于Windows系统中的tasklist 命令
    【云原生 | 60】Docker中通过docker-compose部署kafka集群
    解决编译中遇到的问题:Please port gnulib freadahead.c to your platform
    使用arduino编写mqtt客户端连接emqx服务器
    linux搭建git服务器,windows客户端配置git
  • 原文地址:https://blog.csdn.net/m0_62289613/article/details/126621790