试题链接:http://www.accoders.com/contest.php?cid=1893 考试密码请私信;
T1
明明就是O(n)的模拟,强行打成二分QAQ
思路:判断收尾是否为1或n如果不是自己往上添加山峰,高度是
最接近的山峰的高度+两者之间的差值打完跑一遍即可,大水题.
T1-
旅行日记
1 #include <bits/stdc++.h> 2 using namespace std; 3 int a[1000010][3]; 4 int n,m,maxx,ans; 5 bool ac,wa; 6 int ef(){ 7 for(register int i=0;i<=m;i++){ 8 if(ac==false&&i==0) continue; 9 if(wa==false&&i==m) continue; 10 ans=max(maxx,max(ans,((a[i+1][1]-a[i][1])-abs(a[i][2]-a[i+1][2]))/2+max(a[i][2],a[i+1][2]))); 11 } 12 return ans; 13 } 14 int main(){ 15 scanf("%d%d",&n,&m); 16 for(register int i=1;i<=m;i++){ 17 scanf("%d%d",&a[i][1],&a[i][2]); 18 if(i==1&&a[i][1]!=1){a[0][1]=1;a[0][2]=(a[1][2]+a[1][1]-1);ac=1;maxx=max(a[0][2],maxx);} 19 maxx=max(maxx,a[i][2]); 20 } 21 if(a[m][1]!=n){wa=1;a[m+1][1]=n;a[m+1][2]=(n-a[m][1]+a[m][2]);maxx=max(a[m+1][2],maxx);} 22 for(register int i=0;i<=m;i++){ 23 if(ac==false&&i==0) continue; 24 if(wa==false&&i==m) continue; 25 int midd=a[i+1][1]-a[i][1]; 26 if(abs(a[i+1][2]-a[i][2])>midd){printf("IMPOSSIBLE");return 0;} 27 } 28 cout<<ef(); 29 return 0; 30 }
T2
本题难度中上,思路不太好想
zkc大佬思路:将所有棋子点存储好,用每一个棋子遍历所有
的打击点,存储所有点共有的打击点,然后复制一张图以剩下的攻击
方式消除"o"和"x",若场面上还有"x"则为"NO",若无则为"YES",然
干完了这事后我们以所有打击方式来打击2*n-1那张图,然后输出即
可
事实证明,暴力出奇迹,打表出省一(这么暴力谁想得到啊QAQ)
T2-
奇怪的棋
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n,qwq,lala; 4 char a[110][110]; 5 char heiheihei[110][110]; 6 int dis[130010][3]; 7 int xx[130010][3]; 8 char ans[110][110]; 9 string s; 10 bool check3(int px,int py){ 11 int cnt=0; 12 for(register int i=1;i<=qwq;i++){ 13 int nx=dis[i][1]+px; 14 int ny=dis[i][2]+py; 15 if(nx>=1&&nx<=n&&ny>=1&&ny<=n) 16 if(a[nx][ny]=='x'){ 17 cnt++; 18 if(cnt==qwq) return false; 19 } 20 } 21 return true; 22 } 23 bool check2(){ 24 for(register int i=1;i<=n;i++) 25 for(register int j=1;j<=n;j++){ 26 if(heiheihei[i][j]=='x') return false; 27 } 28 return true; 29 } 30 bool check1(int px,int py){ 31 for(register int i=1;i<=qwq;i++){ 32 int nx=dis[i][1]+px; 33 int ny=dis[i][2]+py; 34 if(nx>=1&&nx<=n&&ny>=1&&ny<=n) if(a[nx][ny]=='.') return false; 35 } 36 return true; 37 } 38 int main(){ 39 scanf("%d",&n); 40 for(register int i=1;i<=n;i++){ 41 cin>>s; 42 for(register int j=0;j<n;j++){ 43 a[i][j+1]=s[j]; 44 if(a[i][j+1]=='o') dis[++qwq][1]=i,dis[qwq][2]=j+1; 45 } 46 } 47 for(register int k=1;k<=qwq;k++){ 48 for(register int i=1;i<=n;i++) 49 for(register int j=1;j<=n;j++){ 50 if((a[i][j]=='x')||(a[i][j]=='o'&&i!=dis[k][1]&&j!=dis[k][2])){ 51 int px=i-dis[k][1],py=j-dis[k][2]; 52 if(check1(px,py)) xx[++lala][1]=px,xx[lala][2]=py; 53 } 54 } 55 } 56 for(register int i=1;i<=n;i++) 57 for(register int j=1;j<=n;j++){ 58 heiheihei[i][j]=a[i][j]; 59 } 60 for(register int i=1;i<=qwq;i++){ 61 heiheihei[dis[i][1]][dis[i][2]]='.'; 62 for(register int j=1;j<=lala;j++){ 63 heiheihei[dis[i][1]+xx[j][1]][dis[i][2]+xx[j][2]]='.'; 64 } 65 } 66 if(check2()) printf("YES "); 67 else{printf("NO ");return 0;} 68 memset(xx,0,sizeof(xx)); 69 lala=0; 70 for(register int k=1;k<=qwq;k++){ 71 for(register int i=1;i<=n;i++) 72 for(register int j=1;j<=n;j++){ 73 if(a[i][j]=='.'){ 74 int px=i-dis[k][1],py=j-dis[k][2]; 75 if(check3(px,py)) xx[++lala][1]=px,xx[lala][2]=py; 76 } 77 } 78 } 79 memset(ans,'x',sizeof(ans)); 80 ans[n][n]='o'; 81 for(register int i=1;i<=lala;i++){ 82 ans[n+xx[i][1]][n+xx[i][2]]='.'; 83 } 84 for(register int i=1;i<=2*n-1;i++){ 85 for(register int j=1;j<=2*n-1;j++) cout<<ans[i][j];printf(" ");} 86 return 0; 87 }
T3
本题找规律,难度中等,但记住要开long long,同时记住每算一个就%一下
思路:在k之后的点不能通往1,所以后面得点不能通往k前
因为k前的点按题意都必须通往1,所以k后的种类数即为(n-k)^(n-k),
在k前的点需要以奇异的算法来算,不难发现在k前的点只要构成循环
或者都指向返回1的点即可成立,所以得出结论在k前的种类数即为
(k-1)^k,最后将两者相乘取mod便可
T3-
小明的城堡
1 #include <bits/stdc++.h> 2 using namespace std; 3 long long modd=1e9+7; 4 long long x,y,ans; 5 long long n,m; 6 long long ksm(long long a,long long b,long long p){ 7 long long ans=1; 8 while(b){ 9 if(b&1) ans=(ans*a)%p; 10 a=(a*a)%p; 11 b/=2; 12 } 13 return ans; 14 } 15 int main(){ 16 scanf("%lld%lld",&n,&m); 17 if(n-m!=0){ 18 x=ksm((n-m)%modd,n-m,modd); 19 } 20 if(n-m==0) x=1; 21 y=ksm(m%modd,m-1,modd); 22 ans=x*y%modd; 23 printf("%lld",ans); 24 return 0; 25 }
end;