2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛 几个写出来了的题目
2016-12-04 23:41
417 查看
2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
几个写出来了的题目
A.
`#include
其实和A题一样,但比赛时想了很久…
n!=1*2*3*…..*n,其中有2的因子的有2,4,6…..,数量为n/2。
取出这些数然后/2,便形成了新的序列1,2,3,4…..,即缩小了问题的规模。
所以只要重复操作即可。
C.
动态规划.dp[i]存放买i本书所需的最小花费。
所以状态转移方程dp[i]=min(dp[i-3]+dp[3],min(dp[i-1]+dp[1],dp[i-2]+dp[2]))
其中dp[1]=a(只有1种买法)
dp[2]=min(a*2,b)(买2个1本或1个2本)
dp[3]=min(c,min(a*3,dp[2]+a))(3个1本,1个1本+1个2本,1个3本)
需要购买的数量为(4-n%4)+4*k本(k为任意自然数)
我的想法:需要买的本数最多的情况是全买1次3本的直到够分,所以dp算到15。
实际上,只有更少的情况:
对于余数为1的情况:买1个1本 ,或者买1个2本+1个3本,或者买3个3本
(a,b,c大于0,不确定的只有这三个数之间的大小关系.其他情况都比这三种情况大)
对于余数为2的情况:买1个2本,或者买2个1本,或者买2个3本
(对于买1个1本1个3本,必定在a+a和c+c之间,所以不予考虑)
对于余数为3的情况:买1个3本,或者买3个1本,或者买1个2本1个1本。
另外:虽然n,a,b,c在1e9以内,但因为涉及到3*a,所以会超出int范围
(我就是因为这个始终没有想明白为什么wrong answer….)
F.
G.
水题.求组合数
I.
深度优先搜索,若向右或下走得通(该点的右边(下边)有路,且目标点的左边(上边)有路),那么就去尝试.找到一条路径后退出。
J.
分别向后搜索、向前搜索,先判断是否为平方数,再取平方根进行素数判断,最后取距离小的。
总之,作为一个新生,还是有很多需要改进的地方。程序只作参考,不一定是简单的思路。
几个写出来了的题目
A.
`#include
#include<stdio.h> int main(void) { long long t,i,j,k,ans,w,s; long long n; scanf("%lld",&t); for (k=1;k<=t;k++) { scanf("%lld",&n); ans=0; while(n) { n/=2; ans+=n; } printf("%lld\n",ans); } return 0; }
其实和A题一样,但比赛时想了很久…
n!=1*2*3*…..*n,其中有2的因子的有2,4,6…..,数量为n/2。
取出这些数然后/2,便形成了新的序列1,2,3,4…..,即缩小了问题的规模。
所以只要重复操作即可。
C.
#include<stdio.h> long long dp[10000]; int min(int a, int b) { if (a>b) return b; else return a; } int main(void) { int n, a, b, c, t, i, j, k, yu, ans; scanf("%d", &t); for (k = 1;k <= t;k++) { scanf("%d %d %d %d", &n, &a, &b, &c); if (n % 4 == 0) { printf("%d\n", 0); continue; } dp[1] = a; dp[2] = min(2 * a, b); dp[3] = min(min(dp[2] + dp[1], dp[1] * 3), c); yu = 4 - n % 4; ans = dp[yu]; for (i = 4;i <= 30;i++) { dp[i] = min(min(dp[i - 1] + a, dp[i - 2] + dp[2]), dp[i - 3] + dp[3]); if (dp[i]<ans && i % 4 == yu) ans = dp[i]; } printf("%d\n", ans); } return 0; }
动态规划.dp[i]存放买i本书所需的最小花费。
所以状态转移方程dp[i]=min(dp[i-3]+dp[3],min(dp[i-1]+dp[1],dp[i-2]+dp[2]))
其中dp[1]=a(只有1种买法)
dp[2]=min(a*2,b)(买2个1本或1个2本)
dp[3]=min(c,min(a*3,dp[2]+a))(3个1本,1个1本+1个2本,1个3本)
需要购买的数量为(4-n%4)+4*k本(k为任意自然数)
我的想法:需要买的本数最多的情况是全买1次3本的直到够分,所以dp算到15。
实际上,只有更少的情况:
对于余数为1的情况:买1个1本 ,或者买1个2本+1个3本,或者买3个3本
(a,b,c大于0,不确定的只有这三个数之间的大小关系.其他情况都比这三种情况大)
对于余数为2的情况:买1个2本,或者买2个1本,或者买2个3本
(对于买1个1本1个3本,必定在a+a和c+c之间,所以不予考虑)
对于余数为3的情况:买1个3本,或者买3个1本,或者买1个2本1个1本。
另外:虽然n,a,b,c在1e9以内,但因为涉及到3*a,所以会超出int范围
(我就是因为这个始终没有想明白为什么wrong answer….)
F.
#include<stdio.h> #include<string.h> int main(void) { printf("ac"); return 0; } 水题
G.
#include<stdio.h> int main(void) { int n,k,i,j,z,x; while (scanf("%d %d",&n,&k)!=EOF) { z=1; x=1; for (i=n;i>=n-k+1;i--) z=z*i; for (i=k;i>=2;i--) x=x*i; if (x==0) z=1; else z=z/x; printf("%d\n",z); } return 0; }
水题.求组合数
I.
#include<stdio.h> struct zt { int left; int right; int up; int down; }; int ans; int n, m; struct zt tu[1010][1010] = { 0 }; void solve(int x, int y) { if (ans == 1) return; if (x == n && y == m) { printf("Well done!\n"); ans = 1; } if (tu[x][y].right 4000 == 1 && tu[x][y + 1].left == 1) solve(x, y + 1); if (tu[x][y].down == 1 && tu[x + 1][y].up == 1) solve(x + 1, y); return; } int main(void) { int t, i, j, k, x, y; char v, b,l; scanf("%d", &t); for (i = 1;i <= t;i++) { scanf("%d %d", &n, &m); for (i = 1;i <= n;i++) for (j = 1;j <= m;j++) { tu[i][j].left = 0; tu[i][j].right = 0; tu[i][j].up = 0; tu[i][j].down = 0; } for (i = 1;i <= n;i++) { getchar(); for (j = 1;j <= m;j++) { scanf("%c%d%c%d%c", &v, &x, &l, &y, &b); switch (x) { case 3: switch (y) { case 0: tu[i][j].left = 1; tu[i][j].right = 1; tu[i][j].down = 1; break; case 1: tu[i][j].up = 1; tu[i][j].left = 1; tu[i][j].down = 1; break; case 2: tu[i][j].up = 1; tu[i][j].left = 1; tu[i][j].right = 1; break; default: tu[i][j].up = 1; tu[i][j].right = 1; tu[i][j].down = 1; break; } break; case 4: tu[i][j].up = 1; tu[i][j].down = 1; tu[i][j].right = 1; tu[i][j].left = 1; break; case 0: break; default: switch (y) { case 0: tu[i][j].left = 1; tu[i][j].right = 1; break; case 1: tu[i][j].up = 1; tu[i][j].down = 1; break; case 2: tu[i][j].left = 1; tu[i][j].down = 1; break; case 3: tu[i][j].up = 1; tu[i][j].right = 1; break; case 4: tu[i][j].up = 1; tu[i][j].left = 1; break; case 5: tu[i][j].down = 1; tu[i][j].right = 1; break; } break; } } } ans = 0; solve(1, 1); if (ans == 0) printf("What a pity!\n"); } return 0; }
深度优先搜索,若向右或下走得通(该点的右边(下边)有路,且目标点的左边(上边)有路),那么就去尝试.找到一条路径后退出。
J.
#include<stdio.h> #include<math.h> int main(void) { int t,n,i,j,k,find,x,left,right; scanf("%d",&t); for (k=1;k<=t;k++) { scanf("%d",&n); find=1; x=n; while (find) { int m=sqrt(x); if (sqrt(x)*sqrt(x)==x) { for (i=2;i<=sqrt(m);i++) { if (m%i==0) break; } if (i>sqrt(m)) {find=0; right=x;} } if (find==1) x++; } find=1; x=n-1; while (find && x>1) { int m=sqrt(x); if (sqrt(x)*sqrt(x)==x) { for (i=2;i<=sqrt(m);i++) { if (m%i==0) break; } if (i>sqrt(m)) {find=0; left=x;} } if (find==1) x--; } if (find==1) printf("%d\n",right); else if (right-n<n-left) printf("%d\n",right); else printf("%d\n",left); } return 0; }
分别向后搜索、向前搜索,先判断是否为平方数,再取平方根进行素数判断,最后取距离小的。
总之,作为一个新生,还是有很多需要改进的地方。程序只作参考,不一定是简单的思路。
相关文章推荐
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛总结
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛 题解&源码
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- Contest1051 - 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
- codeforces 699C(广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛)
- gdutcodeProblem D: 勤奋的涟漪2(新生杯决赛网络同步赛暨全国新生邀请赛)
- 哈尔滨理工大学软件学院ACM程序设计全国邀请赛(网络同步赛)F Fibonacci Again