Test #1 2014/12/6题解
来源:互联网 发布:微商团队怎么优化 编辑:程序博客网 时间:2024/04/27 17:05
题目地址 http://acm.njupt.edu.cn/vjudge/contest/view.action?cid=159#overview
A - Power Strings
其实这道题应该是四道题里最难的一题,但是被黄文锐用暴力给卡了过去。
暴力代码:
#include <stdio.h>#include <string.h>#define len strlen(s)char s[1000000];int main(){int i, j, flag = 0;while (scanf("%s", s) != 1 || s[0] != '.'){for (i = len; i > 0; i--){flag = 1;if (!(len%i)){for (j = 1; j < i; j++){if (strncmp(s, s + len / i * j, len / i)){flag = 0;break;}}if (!flag)continue;else{printf("%d\n", i);break;}}}}return 0;}
虽然这题因为数据不够强的问题让暴力卡了过去,但不是所有这类题目都会数据这么水。
这道题的标算是字符串匹配算法KMP。
附一个我觉得比较好的经典KMP算法的教学贴
http://www.matrix67.com/blog/archives/115
接下来,默认已经会了KMP算法,就可以利用KMP算法中next数组(又叫fail数组,即教学贴中的P数组)的性质
next[i]记录在匹配到B[i],但是B[i+1]匹配失败之后回到的位置。
换句话讲,对于每个next[i],字符串第0位到next[i]位与串第i-next[i]位到i位是一样的。
这样我们可以利用这个性质求出完全相同的前缀和后缀的最长长度。
接下来只要判len/(len-next[len])是否为整数即可,如果为整数的话就是len/(len-next[len])的值,否则n就为1。
标算代码:
#include<iostream>#include <cstdio>#include <cstring>#define MAXN 1000005using namespace std;int next[MAXN],len;char s[MAXN];int main(){ while(scanf("%s",s)!=EOF) { if (strcmp(s,".")==0)return 0; int i=0,j=-1; len=strlen(s); next[0]=-1; while(i<len) //换了一种比较简明的求next数组的写法,本质是一样的。 { if(j==-1||s[i]==s[j]) { i++;j++; next[i]=j; } else j=next[j]; } if (len%(len-next[len])==0) printf("%d\n",len/(len-next[len])); else printf("1\n"); } return 0;}
如果理解了kmp的话,很容易看出这个的时间复杂度是O(n)级别,而暴力是O(n^2)级别的,刚好数据比较水。。。
B - That Nice Euler Circuit
这个就是个阅读理解题,看懂了题目自然就会写了。根据题目弄出公式然后输入数据算即可。
代码:
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>using namespace std;double d,r,t;double C;int main(){int cur=0;while (1){cur++;scanf("%lf%lf%lf",&d,&r,&t);if (r==0)return 0;C=d/5280/12*3.1415927*r; //计算距离printf("Trip #%d: %.2f ",cur,C);C=C*3600/t; //计算MPHprintf("%.2f\n",C);}}
C - 24 Game
这个24点看似很难,其实稍微想一下。
4可以由1*2*3*4算出24,5的话可以由(5+4+3)*2*1算出24。(这只是其中一种构造方法,还有别的方法可以自己思考下。)
接下来所有的大于4的偶数都可以通过n-(n-1)=1得到1,然后不断对24*1即可。
大于5的奇数同理可以不断如此的24*1即可。
代码:
#include <iostream>#include <cstring>#include <cstdio>using namespace std;int n;int main(){scanf("%d",&n);if (n<4)printf("NO\n");else{printf("YES\n");if (n%2==0){for (int i=n;i>=5;i-=2)printf("%d - %d = 1\n",i,i-1);printf("4 * 3 = 12\n2 * 1 = 2\n12 * 2 = 24\n");for (int i=1;i<=(n-4)/2;i++)printf("24 * 1 = 24\n");}else{for (int i=n;i>5;i-=2)printf("%d - %d = 1\n",i,i-1);printf("5 + 4 = 9\n9 + 3 = 12\n12 * 2 = 24\n");for (int i=1;i<=(n-5)/2+1;i++)printf("24 * 1 = 24\n");}}}
D - Balloon Comes!
一个二元的前缀表达式计算,直接读取符号之后计算就行了,唯一要注意的细节就是在除号的时候能否整除要分开处理。
代码:
#include <iostream>#include <cstring>#include <cstdio>#define GC getchar()using namespace std;int a,b;int main(){ int T; scanf("%d",&T); GC; while (T--) { char c=GC; scanf("%d%d",&a,&b); GC; if (c=='+') printf("%d\n",a+b); if (c=='-') printf("%d\n",a-b); if (c=='*') printf("%d\n",a*b); if (c=='/') if (a%b==0) printf("%d\n",a/b); else printf("%.2f\n",(double)a/b); }}
- Test #1 2014/12/6题解
- Test #2 2014/12/7题解
- Test #3 2014/12/13题解
- Intelligence test(test)题解
- codeforces A. IQ test 题解
- 【BZOJ】【P2083】【Poi2010】【Intelligence test】【题解】【二分】
- 【noip 2013 day2题解】【10.28test】
- test.1
- TEST 1#
- Test 1
- Test(1)
- test-1
- 题解 BZOJ-2083 || POI 2010 intelligence test 三种解法
- 2010山东省信息学夏令营模拟赛Test 5.浇水 题解
- 2014 Multi-University Training Contest 1 题解
- 【题解】SWJTU2015.12校队选拔题解
- 2014-3-17 test
- Test-2010-6-25
- linux下iso文件的挂载与卸载
- 静下心来,多学一点
- 这个结构占用的空间为多大呢?()
- initcall func(一)
- Windows 8.1/Windows phone 8.1隐私声明
- Test #1 2014/12/6题解
- interface
- oracle 开发中遇到的问题
- Initcall func(二)
- Linux学习(一):linux更改ip地址命令_更改DNS_更改默认网关_更改子网掩码_主机名
- 从头开始学java--内部类
- linux禁用ipv6
- 笔记《程序员的数学》--感悟之一:关于0
- java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive