第七届ACM趣味程序设计竞赛第四场(正式赛) 题解
2015-12-17 18:18
465 查看
Final Pan's prime numbers
题目连接:
http://acm.uestc.edu.cn/#/problem/show/1272题意
给你n,要求你在[4,n]范围内找到一个最大的质数x,使得x-4和x+4也是质数题解:
数学只有7是满足的
为什么?
1、若 n = 3x,因为n>4,所以n必为合数,不符。 2、若 n = 3x + 1, 则 n - 4 = 3x - 3 = 3(x-1) ,即(n -4 ) % 3 == 0,有且只有n=7时满足 3、若 m = 3x + 2, 则 n + 4 = 3x + 6 = 3 * (x+2),显然n+4为合数,不符 所以n<7时输出-1,n>=7时输出7即可
代码如下:
#include<bits/stdc++.h> using namespace std; int main() { int n;scanf("%d",&n); if(n<7)return puts("-1"); else printf("7\n"); }
ZhangYu Speech
题目连接:
http://acm.uestc.edu.cn/#/problem/show/1269题意
给你n个数,m次询问每次询问是这样的:
输入x
将会构造出一个新的序列,这个新的序列b[i] = a[x] - a[i] (iSum2 输出Keep dis
如果Sum1=Sum2 输出Next time
如果Sum1j的时候)
Sum2+=a[x][j]*(j-s[x]) (s[x]<j的时候)
然后扫一遍10个数就好了~
代码
#include<bits/stdc++.h> using namespace std; int a[100001][11]; int n,m; string s; int main() { scanf("%d%d",&n,&m); cin>>s; for(int i=0;i<s.size();i++) { if(i!=0)for(int j=0;j<10;j++)a[i][j]=a[i-1][j]; a[i][s[i]-'0']++; } while(m--) { int x;scanf("%d",&x); int tmp = s[x-1]-'0'; long long A=0,B=0; for(int i=0;i<10;i++) { if(i<tmp)A+=(tmp-i)*a[x-1][i]; else B+=(i-tmp)*a[x-1][i]; } if(A==B)printf("Next time\n"); else if(A>B)printf("Keep some distance from me\n"); else printf("I agree\n"); } }
Playfair
题目连接:
http://acm.uestc.edu.cn/#/problem/show/1270题意
首先给你一个密码串,你需要通过这个密码串生成5*5的密码矩阵这个密码矩阵的构造方式如下:
这个矩阵依次填入密码串的字符,如果密码串中的字符出现了多次,只算第一次出现的那次。
密码串中的j视作i,大写视作小写。
剩下没有填满的格子,就按照字典序去填。
然后给你一个串,你需要输出加密后的串。
需要忽略除了字母的任何字符,空格。
加密方式如下:
我们首先把串分组,相邻的两个为一组,如果相邻的两个相同的话,就在这两个之间插入一个x。
分组之后,如果同组的元素都在同一行,就输出右边的,如果都在同一列,就输出下面的,如果都不是,就输出mp[l1][r2],mp[l2][r1]
题解:
模拟题认真读题之后,就没什么坑了。。。
模拟题多读几遍 T T(别问我为什么
代码
#include<bits/stdc++.h> using namespace std; int mp[10][10]; int vis[30]; int l[30]; int r[30]; string s,txt,temp,txt1; int main() { vis['j'-'a']=1; cin>>s; int tot = 0,flag = 0; for(int i=0;i<s.size();i++) if(s[i]=='j')s[i]='i'; for(int i=0;i<5;i++)//构造密码矩阵 { for(int j=0;j<5;j++) { if(s[tot]=='j') s[tot]='i'; while(tot<s.size()&&vis[s[tot]-'a']) tot++; if(tot==s.size())flag = 1; if(flag){for(int k=0;k<26;k++) if(vis[k]==0){mp[i][j]=k;break;}} else mp[i][j]=(int)(s[tot]-'a'); vis[mp[i][j]]=1; } } for(int i=0;i<5;i++) for(int j=0;j<5;j++) l[mp[i][j]]=i,r[mp[i][j]]=j; while(cin>>temp)txt1+=temp; //大写变小写,去掉奇怪的东西 for(int i=0;i<txt1.size();i++) { if(txt1[i]<='Z'&&txt1[i]>='A') txt1[i]=txt1[i]-'A'+'a'; if(txt1[i]=='j')txt1[i]='i'; if(txt1[i]<='z'&&txt1[i]>='a')txt+=txt1[i]; } for(int i=0;i<txt.size();i++) { if(i==txt.size()-1)break; if(txt[i]==txt[i+1]) { int l1 = l[txt[i]-'a']; int r1 = r[txt[i]-'a']; int l2 = l['x'-'a']; int r2 = r['x'-'a']; if(l1 == l2) cout<<(char)(mp[l1][(r1+1)%5]+'a')<<(char)(mp[l2][(r2+1)%5]+'a'); else if(r1 == r2) cout<<(char)(mp[(l1+1)%5][r1]+'a')<<(char)(mp[(l2+1)%5][r2]+'a'); else cout<<(char)(mp[l1][r2]+'a')<<(char)(mp[l2][r1]+'a'); } else { int l1 = l[txt[i]-'a']; int r1 = r[txt[i]-'a']; int l2 = l[txt[i+1]-'a']; int r2 = r[txt[i+1]-'a']; if(l1 == l2) cout<<(char)(mp[l1][(r1+1)%5]+'a')<<(char)(mp[l2][(r2+1)%5]+'a'); else if(r1 == r2) cout<<(char)(mp[(l1+1)%5][r1]+'a')<<(char)(mp[(l2+1)%5][r2]+'a'); else cout<<(char)(mp[l1][r2]+'a')<<(char)(mp[l2][r1]+'a'); i++; } } }
Search gold
题目连接:
http://acm.uestc.edu.cn/#/problem/show/1271题意
给你n行m列的矩阵,你一开始在(1,1)这个位置,如果你到某个格子,你身上的权值就会加上a[i][j],如果你权值为负数,就会死掉问你在保证不走出去,以及不死掉的情况下,权值最多为多少
一开始在(x,y),下一步可以走到(x+1,y)(x,y+1)(x+2,y+1)(x+1,y+2)
题解:
动态规划dp[i][j]表示走到当前格子所能获得的最大权值,很显然dp[i][j]=max(dp[i-1][j],dp[i][j-1],dp[i-2][j-1],dp[i-1][j-2])+a[i][j]转移过来的
稍微注意下,如果dp[x][y]为负数的话,就不要从这儿转移过来就好了
代码:
#include<bits/stdc++.h> using namespace std; const long long inf = 9999999999999LL; long long dp[1002][1002]; long long a[1002][1002]; int dx[5]={1,0,1,2}; int dy[5]={0,1,2,1}; int n,m; int check(int x,int y) { if(x<1||x>n)return 0; if(y<1||y>m)return 0; return 1; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { dp[i][j]=-inf; scanf("%lld",&a[i][j]); } dp[1][1]=a[1][1];long long ans = -1; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(dp[i][j]<0)continue; ans = max(ans,dp[i][j]); for(int k=0;k<4;k++) { int x = i+dx[k]; int y = j+dy[k]; if(!check(x,y))continue; dp[x][y]=max(dp[i][j]+a[x][y],dp[x][y]); } } } cout<<ans<<endl; }
God Qing's circuital law
题目连接:
http://acm.uestc.edu.cn/#/problem/show/1273题意
有n个男孩子,n个女孩子,男孩子和女孩子可以组合在一起,组合一起的Value = p[i] * v[i]然后问你,一共有多少种组合,第一个人的组合,能力值最高
题解:
暴力容斥首先我们枚举每一个女孩子和第一个人组合的情况
然后枚举后面的熊孩子,对于每个熊孩子再数出一共有多少种组合比他厉害,就可以暴力容斥了~
代码
#include<bits/stdc++.h> using namespace std; #define maxn 120 const int mod = 1e9 + 7; long long a[maxn]; long long b[maxn]; long long c[maxn]; bool cmp(int A,int B) { return A>B; } int main() { int n; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%lld",&a[i]); for(int i=0;i<n;i++) scanf("%lld",&b[i]); sort(a+1,a+n,cmp); sort(b,b+n); long long ans = 0; for(int i=0;i<n;i++) { long long p = a[0]*b[i]; int tot = 0; long long k = b[i]; for(int j=0;j<n;j++) { if(j==i)continue; c[tot++]=b[j]; } long long ans2 = 1; int flag = 0; for(int j=1;j<n;j++) { long long tmp = -1; for(int t=0;t<tot;t++) { if(a[j]*c[t]>=p) break; tmp = t; } tmp = tmp + 2 - j; if(tmp<=0) { flag = 1; break; } ans2 = (ans2 * tmp)%mod; } if(flag==0) ans = (ans + ans2)%mod; } printf("%d\n",ans); }
Open the lightings
题目连接:
http://acm.uestc.edu.cn/#/problem/show/1268题意
给你n栈灯,一开始只有第m盏灯是亮着的。然后你可以打开第i盏灯,如果第j盏灯是亮着的,而且abs|j-i|<=2
然后问你一共有多少种方式能够打开所有灯
题解:
动态规划f
表示开了n盏灯的方案数,则f
=(f[n-2])*(n-1)+f[n-1]。
由于第一盏灯的两方相互不影响,设i为最初的灯 则答案为f[i-1]f[n-i]c(n-1,i-1)
代码
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #define LL long long using namespace std; const LL oo=1000000007; LL n,m,i,j,c[1111][1111],b[1111],ans; int main(){ scanf("%I64d%I64d",&n,&m); if(n==1){ printf("1\n");return 0; } b[1]=1;b[2]=2; for(i=3;i<=n;++i){ b[i]=(((b[i-2])*(i-1))%oo+b[i-1])%oo; } if(m==n||m==1){ printf("%I64d\n",b[n-1]); return 0; } c[0][0]=1; for(i=1;i<=n;++i){ c[i][0]=1; for(j=1;j<=i;++j)c[i][j]=(c[i-1][j]+c[i-1][j-1])%oo; } ans=((b[m-1]*b[n-m])%oo*c[n-1][m-1])%oo; printf("%I64d\n",ans); return 0; }
相关文章推荐
- xamarin跨平台iOS、Android 与Windows
- Mysql String Functions
- textarea替换换行和空格的方法
- 获取LayoutInflater的三种方式
- Android签名机制:生成keystore、签名、查看签名信息
- struct和typedef struct
- SpringMVC学习笔记001-服务器端获取JSON字符串并解析
- 备份脚本小结
- ECharts Java 动态加载数据,echartsjava
- Linux下Gcc生成和使用静态库和动态库详解
- linux中 OpenGL 出现 undefined reference to `gluLookAt' 报错
- cellForRowAtIndexPath不执行
- 3D图片采集与展示(SurfaceView 自适应 Camera, 录制视频, 抽取帧)
- android模拟器修改时间
- <c:out value="" />出错
- CentOS6.5X86_64系统定制文档详细版
- Linux软件包管理器之rpm和yum详解
- appium的几点总结
- State Threads 回调终结者
- java中反射的原理