奋斗群群赛12总结与心得(缺4)

来源:互联网 发布:淘宝特卖女装清仓棉袄 编辑:程序博客网 时间:2024/05/22 14:17

  • 总体情况
  • T1
    • 题目
    • 思路
  • T2
    • 题目
    • 思路
  • T3
    • 题目
    • 思路
  • T5
    • 题目
    • 思路

总体情况

https://vjudge.net/contest/186412
本次题目除了D可以说全是水题,E题也能轻松搞定。

T1

题目

给幼儿园的n个小孩发糖,第i个小孩要a[i]颗糖,你每次发给第一个小孩k颗,如果他需要的糖已经满了,他就回家,否则他排到队伍的最后,如此循环。输出最后剩下的小孩的编号。

思路

暴力模拟。一开始因为初始化出错挂了好几次。这个代码还是很复杂,为了简化时间我直接暴力判断是不是只剩下一个小孩。

#include<bits/stdc++.h>using namespace std;int a[1000];bool judge(int n){int i,s=0;for (i=1;i<=n;i++) if (a[i]>0) s++;return s==1?1:0;}int main(){int n,i,k,t=1;cin>>n>>k;for (i=1;i<=n;i++) cin>>a[i];while (!judge(n))  {  if (a[t]>0) a[t]-=k;  t++;  if (t>n) for (i=1;i<=n;i++) if (a[i]>0) {t=i;break;}  }for (i=1;i<=n;i++) if (a[i]>0) cout<<i;}

T2

题目

有一个数列,f[1]=x,f[2]=y,从第二项开始满足f[i]=f[i-1]+f[i+1].求数列第n项mod1000000007的值。

思路

列出数列可以知道数列六个一循环。计算出前六个数,求出它们mod1e9+7的值,按照周期问题解决。搞定一些玄学问题之后成功AC.这里给出两个代码。首先搞定负数小于-1e9-7的情况,再解决数字太大的情况。

#include<bits/stdc++.h>using namespace std;const long long mod=1e9+7;long long a[10];int main(){long long i,n;cin>>a[1]>>a[2]>>n;for (i=3;i<=6;i++) a[i]=a[i-1]-a[i-2];for (i=1;i<=6;i++) while (a[i]<0) a[i]=(a[i]+mod)%mod;for (i=1;i<=6;i++) a[i]=(a[i]+mod)%mod;n=n%6;if (n==0) n=6;cout<<a[n];}

没有想到一开始的代码加两个mod就过了。

#include<bits/stdc++.h>using namespace std;const long long mod=1e9+7;long long a[10];int main(){long long i,n;cin>>a[1]>>a[2]>>n;for (i=3;i<=6;i++) a[i]=a[i-1]-a[i-2];for (i=1;i<=6;i++) a[i]=(a[i]+2*mod)%mod;n=n%6;if (n==0) n=6;cout<<a[n];}

T3

题目

巧克力是一整块,分成n*m个小方格。现在你切k刀,每刀必须切在方格的接缝上,不能重复。输出你能让切出的巧克力中最小的一块含有的方格最多,输出这个数字。如果不能切k刀,输出“-1”。

思路

明显最多能切n+m-2刀,如果k大于这个数字输出-1。然后尽量朝着一个方向切,这样切能切成的巧克力块数最少并且能够使数量尽可能平均。具体看代码。这么简单的题又爆int!!我秒了它!

#include<bits/stdc++.h>using namespace std;long long n,m,k;int main(){cin>>n>>m>>k;long long da=max(m,n),xiao=min(m,n),t;if (k<da) t=max(da*(xiao/(k+1)),xiao*(da/(k+1)));//在一边切else t=max(da/(k-xiao+2),xiao/(k-da+2));//一边全部切完之后尽量均分切另一边if (t==0) t=-1;cout<<t; }

T5

题目

给出一个<=100000的正整数,将2-它之间的数字分成两个一组,每组中的两个数字满足最大公约数大于1,求能分成最多的组数.

思路

首先用筛法筛出1-n之间的质数,然后从小到大枚举所有质数以及它的平方.把小于n的数对找出来.接下来从2开始暴枚,找到第一个没有用过的数字.一开始我暴枚TLE,优化之后时间没有问题,但是因为是从小到大枚举出错了.
最后大佬告诉我,从n/2开始倒数到2枚举质数,对于每个质数找到没有用过的它的倍数,一对一对拿出来.如果一共有奇数个,找出2i(一定是偶数,可以在最后枚举到2的时候用上).有了想法代码还是比较简单能写出来的,如下.没有料到的是我i循环里套i循环我没检查出来调了一个小时!

#include<bits/stdc++.h>using namespace std;const int boss=1e5;pair<int,int> nico[boss+10];bool p[boss+10],used[boss+10];int n,a[boss+10];void doing_prime(int n){int i,j;for (i=2;i*i<=n;i++) if (p[i]==0)for (j=i*i;j<=n;j+=i) p[j]=1;}int main(){int i,j,t=0,answer=0;scanf("%d",&n);doing_prime(n);for (i=n/2;i>1;i--)  {   if (p[i]) continue;  t=0;  for (j=i;j<=n;j+=i) if (used[j]==0) a[++t]=j;  if (t&1) swap(a[2],a[t]);  for (j=1;j<t;j+=2)     {    nico[++answer]=(make_pair(a[j],a[j+1]));    used[a[j]]=used[a[j+1]]=1;    }  }printf("%d\n",answer);for (i=1;i<=answer;i++) printf("%d %d\n",nico[i].first,nico[i].second);}
原创粉丝点击