题目B:咖啡店
我当时的麻烦方法, #includeusing namespace std; int main() { int n,a; cin>>n>>a; int n1=a/5; if(n==0){ cout<<0<<' ' 题目C:kiki和bob玩取石子
#includeusing namespace std; int main() { int n; scanf("%d",&n); //取石子游戏,最后把石子取完的那一个人获胜 ! if(n%4!=0)cout<<"kiki"< 题目D:猴王kiki分桃
方法1: #includeusing namespace std; int main() { long long n,l,r; cin>>n>>l>>r; long long max=0; //我的循环法98ms for(int i=l;i<=r;i++){ int q=i%n; if(q>max)max=q; //靠max比较折腾 } cout< using namespace std; int main() { long long n,l,r; cin>>n>>l>>r; long long a,b; //无非就是l到r之间的求余取最大,最大总小于等于n-1 a=l/n; b=r/n; if(a 题目E:很2的拆分
方法1: #includeusing namespace std; int main() { unsigned long long n; cin>>n; if(n%2!=0){ cout<<-1< =0;i--){ //2进制的位运算 i=2 110B 得值100B if(n>>i&1)cout<<(1< using namespace std; int main() { unsigned long long n,q=1; cin>>n; if(n%2!=0){ cout<<-1< n)q/=2; while(n){ if(n>=q){ n-=q; //只要还能减就,就不断减去n的值 cout< 题目F:构造字符串
#includeusing namespace std; char a[2423]; int cnt=0; int n; char q[2456]; int i=0; int f(int w,int r); int main() { cin>>n; scanf("%s",a); while(i<=n-1){ if(a[i]>a[n-1])q[cnt++]=a[n-1],n--; else if(a[i]a[z-1])q[cnt++]=a[n-1],n--; else if(a[x+1] 题目G:信号之旅
#includeusing namespace std; int main() { int t; cin>>t; while(t--){ int xa,ya; //这题在比赛的时候看都没看几眼,赛后回顾真感觉太后悔了 cin>>xa>>ya;//典型的长题干简单题 int xb,yb; //模型就是从A走到B,若挡住总步数记作X cin>>xb>>yb;//只有A与B的横纵坐标其一相同的,P在AB间,P挡得住,总步数X+2 int xp,yp; cin>>xp>>yp; if(xa!=xb&&ya!=yb)cout m)))cout< 题目H:小球滚动
#includeusing namespace std; #define m 1111121 int a[m]; int main() { int l,n; //小球间无区别,可将小球相遇后饭后当作保持原样交叉通过 cin>>l; //每只小球可看作在独立滚动,互相间不影响 cin>>n; //所以要求最长/短时间,只需求其中的小球到端口(左右其一)的最大/最小的距离 int max1=0,min1=0; //注意此处min1为0,与下处对应 for(int i=1;i<=n;i++){ cin>>a[i]; max1=max(max1,max(a[i],l-a[i])); min1=max(min1,min(a[i],l-a[i]));//注意此处用max函数,因为要所有球全部通过 } cout< 题目I:kiki看球赛
#includeusing namespace std; int a[134242]; int b[121424]; int main() { int n; cin>>n; int cnt=0;//注意不可忽略前一组低分追平的情况 int q=0,w=0; for(int i=1;i<=n;i++){// 3 21 32 42//3 30 34 44//3 30 40 44 cin>>a[i]>>b[i];// 2 34 44 // 3 30 43 45//3 30 44 45 q=max(a[i-1],b[i-1]);//记录上一组的最大 w=min(a[i],b[i]);//记录这一组的最小 if(w>=q){//这个if也可以不要,反正w-q一减后面的再一加就消掉了 cnt+=w-q+(a[i-1]!=b[i-1]); //若前次记录的是ab不等,还需+1,对应前一组低分追平 } } cout< 题目J:跳一跳
#include#define N 1353533 using namespace std; int a[N]; long long n; //每"到"一块瓷砖,则更新当前所能到达瓷砖的最大值 int main() { long long i;//注意在下列的for循环中i的格式与n要对齐 long long ans=1;//同上,所有数据在long long的范围内 cin>>n; for(i=1;i<=n;i++){ cin>>a[i]; } //如果用寻常的1~n的遍历,会遍历到不可到达的瓷块,必错 for(i=1;i<=min(n,ans);i++)//这里的i<=min(n,ans)是精髓,代表遍历到可以到达的所有瓷块; ans=max(ans,i+a[i]);// 等同if(ans=n) break;//凡是超出或到达瓷块的数量值则退出 } ans=min(n,ans);//注意超出瓷块数量的处理 printf("%lldn",ans); return 0; } 知识点:循环条件的变化处理,min换if更简单便捷,注意对范围超出的处理 题目K:Jay的小迷弟
#includetypedef long long LL; const LL mod =1e9+7; const LL maxn=1e8+5; using namespace std; char ch[maxn]; LL n; LL cnt_Jay,cnt_J,cnt_a,cnt_y; LL fpow(LL a,LL b) { LL res=1; //为避免出来大数,超出范围,while里面要套%mod,所以不用pow,整这个结构 a%=mod; //来给你举例一下,这下面的结构是个绝对的好东西 while(b){ //4D(100B)--循环1--resX1--循环2--resX1--循环3--resX(4X4) 总X16 if(b&1)res*=a%mod; //3D(11B)---循环1--resX2--循环2---resX2X2 总X8 b>>=1; //2D(10B)--循环1--resX1---循环2---resX2X2 总X4 a*=a%mod; //1D(1B)---循环1--resX2--- 总X2 ,数据越大,省的循环越多! } //这不比while里面套b--快得多?肯定得啊! return res; } int main() { LL i,j; scanf("%s",ch+1); n=strlen(ch+1); //这里得ch+1都是为得下面 for循环里头由1~n遍历 和第一个if里头i<=n-2 for(i=1;i<=n;i++){ if(i<=n-2&&ch[i]=='J'&&ch[i+1]=='a'&&ch[i+2]=='y'){ cnt_Jay++; i+=2; } else if(ch[i]=='a')cnt_a++; else if(ch[i]=='J')cnt_J++; else if(ch[i]=='y')cnt_y++; } LL ans=0; ans=min(cnt_J,min(cnt_a,cnt_y)); if(ans==0&&cnt_Jay>0){ ans=1; cnt_Jay--; } ans%=mod; //这里必不能忘取模 ans=ans*fpow(2,cnt_Jay)%mod;//这里也是,给它取模一下 printf("%lldn",ans); return 0; } 知识点:这里的fpow结构(结构内为避免大数反复取模,善用位运算,减少循环次数) 好东西: //LL fpow(LL a,LL b) //{ // LL res=1; // a%=mod; // while(b){ // if(b&1)res=res*a%mod; // b>>=1; // a=a*a%mod; // // } // return res; //} 题目L:翻转卡片
//看着有点麻烦,偷个懒,先放个学长的题解,以后再融入自己的理解,有空再编嘿嘿 //分数取模需要提前了解费马小定理+快速幂 //考虑动态规划,此题状态定义的方式有很多种,我们定义dp[i][j][k]代表:i张卡片,已经翻 //转了k张的方法数,j==0表示最后一张卡片未翻转,j==1表示最后一张卡片已经翻转,显然dp[i][0][k] //=dp[i-1][1][k],dp[i][1][k]=dp[i-1][0][k-1]+dp[i-2][0][k-1].那么i张卡片翻转k张的总方法数就 //等于(dp[i][0][k]+dp[i][1][k]*fact(k),其中fact(k)表示k的阶乘,接下来甲酸期望即可 #includeusing namespace std; const int mod=(int)1e9+7; long long mypow(long long a,long long n) { long long ans=1; while(n){ if(n&1)ans=ans*a%mod; a=a*a%mod; n>>=1; } return ans; } long long dp[10000][2][5000]; long long cnt[10000]={0,1,2}; long long expect[10000]; long long fact[10000]; int main() { fact[0]=fact[1]=1; for(int i=2;i<=1000;++i){ fact[i]=fact[i-1]*i%mod; } dp[1][1][1]=1; dp[2][1][1]=1; dp[2][0][1]=1; for(int i=3;i<=1000;++i){ for(int j=1;j<=(i+1)/2;++j){ dp[i][0][j]+=dp[i-1][1][j]; dp[i][1][j]+=dp[i-1][0][j-1]; dp[i][1][j]+=dp[i-2][0][j-1]; dp[i][0][j]%=mod; dp[i][1][j]%=mod; cnt[i]+=((dp[i][0][j]+dp[i][1][j])%mod*fact[j]%mod); cnt[i]%=mod; } } for(int i=1;i<=1000;++i){ for(int j=0;j<=(i+1)/2;++j){ expect[i]+=((dp[i][0][j]+dp[i][1][j])%mod*fact[j]%mod)*j%mod; expect[i]%=mod; } expect[i]=expect[i]*mypow(cnt[i],mod-2)%mod; } int tt; cin>>tt; while(tt--){ int n; cin>>n; cout< 哈尔滨理工大学21级新生程序设计竞赛(同步赛)_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com)



