作为一个真正意义上的菜鸟,A掉了4题。。。。。
比赛暴漏了很多问题,最大的就是代码控制能力不强,很多简单的题不能在很短的时间内敲出来,说明还是打的少。以后尽量少看别人代码,争取通过自己的思考做题,这样碰到同类的题才能迅速A掉。
下面是我做出来的5道题的简单分析:
其中的1002、1005、1008都是真正意义上的水题。
1002:
每5个字符转换一次,遇到字母就是0,遇到数字就是1,然后得出这5个数字对应的10进制数字,对应到26个英文字母就是答案。
代码如下:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
#define max(a, b) a > b ? a : b
#define min (a, b) a < b ? a : b
#pragma comment(linker, "/STACK:102400000,102400000")
char ans[26] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
int main()
{
int len;
char str[10010];
int sum;
while(scanf("%d", &len) != EOF)
{
scanf("%s", str);
for(int i = 0; i < len; i += 5)
{
sum = 0;
for(int j = i; j < i + 5; ++j)
{
if(str[j] >= '0' && str[j] <= '9')
sum += pow(2.0, 4 - j % 5);
}
printf("%c", ans[sum]);
}
printf("\n");
}
return 0;
}
1005:
KFC排队问题,简单的数学问题。读清楚题就可以迅速A掉。
代码如下:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
int b, d, f, p;
char que[10010];
int sum(char a)
{
if(a == 'A')
return (b + d + f);
else if(a == 'B')
return (2 * b + 2 * d + p);
else
return (3 * b + 3 * d + 2 * p);
}
int main()
{
int n;
int ans, len, mincost;
while(scanf("%d%d%d%d%d", &n, &b, &d, &f, &p) != EOF)
{
mincost = 9999999;
for(int k = 0; k < n; ++k)
{
scanf("%s", que);
len = strlen(que);
ans = 0;
for(int i = 0; i < len; ++i)
ans += sum(que[i]);
if(mincost > ans)
mincost = ans;
}
printf("%d\n", mincost);
}
return 0;
}
1008:
比较2个字符串,看看主串中含有多少个不重叠的子串,开始以为是KMP,发现很多人迅速水过,想着应该是纯暴力啊。。。KMP可不是一时半会就可以理解的。于是果断暴力,果断A掉了。。。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
char s[1000050], p[10];
int main()
{
int ncase;
int lens, lenp;
int i, j, k, sign;
int sum;
scanf("%d", &ncase);
while(ncase--)
{
scanf("%s%s", s, p);
lens = strlen(s);
lenp = strlen(p);
sum = 0;
for(i = 0; i < lens; ++i)
{
int k = i;
for(j = 0; j < lenp; ++j)
{
if(s[k] == p[j])
k++;
else
break;
}
if(j == lenp)
{
sum++;
i += lenp - 1;
}
}
printf("%d\n", sum);
}
return 0;
}
1001和1006是比较难的。其中1006是比赛后A的。。。
1001:
可以把式子分解为:(y-x)(y+x)=n,设y-x=a,y+x=b.然后通过枚举得出结果。但是TLE了。后来听数学系的同学给了一点思路,发现通过均值不等式可以大大减少枚举的个数,通过对num开平方,从中间开始向下找因子,找到的第一个肯定就是x的最小值(x=(a-b)/2),a-b的值越小,说明ab越接近,这点均值不等式可以说明。所以做法就是先对num开平方,得到temp,然后从temp向下枚举,找到的第一个a,b就是答案。但是需要注意的是x是正整数,所以a和b不能相等。相等x=0,这点注意一下就可以了。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int main()
{
int ncase;
int num, temp;
bool flag;
scanf("%d", &ncase);
while(ncase--)
{
scanf("%d", &num);
flag = false;
temp = (int)sqrt(num * 1.0);
for(int i = temp; i >= 1; --i)
{
if(num % i != 0)
continue;
else
{
if((i + num / i) % 2 == 0 && i != num / i)
{
printf("%d\n", (num / i - i) / 2);
flag = true;
break;
}
}
}
if(!flag)
printf("-1\n");
}
return 0;
}
1006:
这道题确实是一个难度很大的找规律题,后来发现matrix67大神博客上有这个数列的介绍,只要看下这篇博客就应该能搞定了。其实就是一个简单的模拟而已。
就是判断上一个数列的1,2,3的个数,比如1221,则从左向右遍历,发现有1个1,所以是“11”,然后有2个2,所以加上“22”,变成“1122”,然后是1个1,加上“11”,成为“112211”。其实就是判断数列从左到右重复数字出现的个数。
文章链接:http://www.matrix67.com/blog/archives/3870/comment-page-1
代码如下:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
int p[32] = {0, 1, 2, 2, 4};
string s[32] = {"", "1", "11", "21", "1211"};
void fast(int n)
{
int len = s[n - 1].length();
int sum = 1;
for(int i = 0; i < len - 1; ++i)
{
if(s[n - 1][i] != s[n - 1][i + 1])
{
if(i == len - 2)
{
s[n] += (sum + '0');
s[n] += s[n - 1][i];
s[n] += '1';
s[n] += s[n - 1][i + 1];
}
else
{
s[n] += (sum + '0');
s[n] += s[n - 1][i];
sum = 1;
}
}
else
{
sum++;
if(i == len - 2)
{
s[n] += (sum + '0');
s[n] += s[n - 1][i];
break;
}
}
}
p[n] = s[n].length();
}
int main()
{
int n;
for(int i = 5; i <= 30; ++i)
fast(i);
while(scanf("%d", &n) && n)
{
printf("%d\n", p[n]);
}
return 0;
}
//打表~
#include<cstdio>
int main()
{
int n;
int p[30] = {1, 2, 2, 4, 6, 6, 8, 10, 14, 20, 26, 34, 46, 62, 78, 102, 134, 176, 226, 302, 408, 528, 678, 904, 1182, 1540, 2012, 2606, 3410, 4462};
while(scanf("%d", &n), n)
printf("%d\n", p[n - 1]);
return 0;
}