因为最近一直有新acmer问我问题,然后最近脑子也不会想,然后看到这题的来源,就把这套题目给做了,相比于其他校赛或者练习赛,这场的题目很水,勿碰、
A 天降RP
B 网上交作业的烦恼
Description
每星期三就要开始网上交汇编作业了,WY早早的开始在网上找好汇编的答案。大家知道课后习题都有序号的。答案上也标有序号(1),(2),(3)……但是老师说了只要交序号为素数的题目。WY准备去删除那些序号非素数的题目在答案里,他发现题目好多手工删除实在费力啊 重复同样动作而且。所以他想请你帮忙解决下。
Input
输入以文件结尾。输入多行数据,最多200行。每行代表一个题目,也就是说题目最多才200题。每个题目都只有字符组成,每个题目字符最多1000000个。题目之间换行.
Output
输出删除了非素数序号的题目。题目之间换行。数据肯定合法。(按例子)
Sample Input
(1)ACBDS (2)Gdfg7&fd (3)Dguyuy*fd% (4)Sfdggggg (5)tttthdsf@
Sample Output
(2)Gdfg7&fd (3)Dguyuy*fd% (5)tttthdsf@
就是素数的判断了,而且还是200以内的素数,还有需要注意的是取的是括号里面的数,一开始我就直接从tt[1]到tt[4]里面判断数字了,有可能是(2)5sflksfksld类似这样的
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define N 210
char tt[1000010];
int prime[N];
bool is_prime[N + 10];
void sieve(int n)
{
int p = 0;
for(int i = 0; i <= n; i ++)
is_prime[i] = true;
is_prime[0] = is_prime[1] = false;
for(int i = 2; i <= n; i ++)
{
if(is_prime[i])
prime[p ++] = i;
for(int j = 2* i; j <= n; j += i)
{
is_prime[j] = false;
}
}
}
int main()
{
int cnt = 0;
memset(is_prime, 0, sizeof(is_prime));
sieve(210);
/*for(int i = 1; i <= 110; i ++)
{
printf("%d\n",prime[i]);
}*/
while(~scanf("%s",tt))
{
int tm = 0;
for(int i = 1; i <= 4; i ++)
{
if(tt[i] <= '9' && tt[i] >= '0')
tm = tm *10 + tt[i] - '0';
if(tt[i] == ')')
break;
}
if(is_prime[tm])
printf("%s\n",tt);
}
}
C 打印图形
不想搞
D: 玉树搜救行动
Description
自从玉树受灾以来,有关部门一直在现场抢救落难的人。他们用个种方法搜救,用上了搜救犬,有了搜救犬找到生命迹象就容易了。
假设现场用一个矩阵表示,抢救的有多条搜救犬,受灾的人也有多个可能。
例子:
#p.d#p#
#####.#
d……..#
######p
d表示搜救狗,p表示受灾的人,点表示可以通行的路,#表示石头挡住的路,不能通行。
搜救狗只能上下左右走,不能越过障碍物。
上面的那个例子最多可以救到2个人。因为第三个人被四周包围搜救狗无法到达。
Input
输入数据有多组。每组两个整数R,C, 2=<R,C<=100, R表示矩阵的行数,C表示矩阵的列数,然后输入相应矩阵,矩阵保证有搜救狗和受灾的人。当输入R=0且C=0时候输入结束。
Output
输出搜救狗最多能救多少受灾的人的数量。
Sample Input
4 7 #p.d#p# #####.# d.....# ######p 0 0
Sample Output
2
简单的搜索,注意从p位置搜d 比较好,不然容易超时
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
int dir[4][2] = {1,0,-1,0,0,1,0,-1};
bool vis[110][110];
bool vis1[110][110];
char tt[110][110];
int n, m;
int cnt;
struct node
{
int x, y;
};
void bfs(int x, int y)
{
memset(vis, false, sizeof(vis));
vis[x][y] = true;
queue<node> qe;
while(!qe.empty())
{
qe.pop();
}
node a, tmp, next;
a.x = x;
a.y = y;
qe.push(a);
while(!qe.empty())
{
tmp = qe.front();
qe.pop();
for(int i = 0; i < 4; i ++)
{
int xx = tmp.x + dir[i][0];
int yy = tmp.y + dir[i][1];
if(xx >= 0 && yy >= 0 && xx < n && yy < m && !vis[xx][yy] && tt[xx][yy]!= '#')
{
if(tt[xx][yy] == 'd')
{
cnt ++;
return;
}
next.x = xx;
next.y = yy;
vis[xx][yy] = true;
qe.push(next);
}
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n == 0 && m == 0)
break;
cnt = 0;
memset(vis1, false, sizeof(vis1));
for(int i = 0; i < n; i ++)
{
scanf("%s",tt[i]);
}
for(int i = 0; i < n; i ++)
{
for(int j = 0; j < m; j ++)
{
if(tt[i][j] == 'p')
bfs(i, j);
}
}
printf("%d\n",cnt);
}
return 0;
}
E: 穿越通道
Description
有个helihui建造的通道,这个通道比较奇怪,我们把通道看成平面的,里面全是数字,看例子:
走的时候只能一格一格的走,走的方向只能往下或往右,并且不能走出边界。从入口进来,每个格子代表通过这个格子的时间。Helihui规定最左上角是通道入口, 最右下角是通道出口,现在要求你判断从入口到出口的所有路径中总时间最小的那条路径。并输出通过该条路径的总时间,上面的红色箭头是表示这样走可以得到最小的总时间。
Input
输入数据有多组。
每组输入n,m整数,n表示通道格子的行数,m表示通道格子的列数,0<n,m<100,接下来输入n行m列的矩阵,矩阵的数据的范围0到32765。
走的时候从通道入口进入从出口出去,并且通道入口一直在最左上角,通道出口一直在最右下角。
Output
输出从入口到出口所有路径中最短时间。
Sample Input
4 6 3 4 3 2 5 2 1 6 7 5 3 1 2 1 8 6 9 1 7 10 4 6 7 8
Sample Output
29
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
int tt[110][110];
int dp[110][110];
int main()
{
int n, m;
while(~scanf("%d%d",&n,&m))
{
memset(tt, 0, sizeof(tt));
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{
scanf("%d",&tt[i][j]);
//dp[i][j] = 9999999;
}
}
for(int i = 0; i <= 110; i ++)
{
for(int j = 0; j <= 110; j ++)
{
dp[i][j] = 9999999;
}
}
for(int i = 1; i <= m; i ++)
{
tt[1][i] += tt[1][i - 1];
dp[1][i] = tt[1][i];
}
for(int i = 2; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + tt[i][j];
}
}
printf("%d\n",dp[n][m]);
}
}
F: 单词后缀
Description
有些英语单词后缀都是一样的,现在我们需要从给定的一堆单词里面找出某个后缀的单词个数。
Input
输入有多组数据。
每组第一行输入n,m,0<=n,m<=100000,
第二行到n+1行:输入单词,每个单词仅有小写英文字母组成,长度不超过10。
第n+2行到n+m+1行,输入要找的单词后缀。
Output
在n个单词里面找出输入单词后缀的单词个数,然后输出。每个数据与数据之间换行。
Sample Input
6 3 someone everyone outside inside somebody nobody one side body
Sample Output
2 2 2
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
struct Node
{
int sum;
Node *lt[28];
}a[500100];
Node *head;
int cnt = 0;
void insert (char str[])
{
int i, j;
Node *t, *s = head;
int len = strlen(str);
for (i = 0; i < len; i ++)
{
int id = str[i] - 'a';
if(s->lt[id] == NULL)
{
t = &a[cnt++];
for(j = 0;j < 26;j ++)
{
t->lt[j] = NULL;
}
t->sum = 0;
s->lt[id] = t;
}
s = s->lt[id];
s->sum++;
}
}
int query (char str[])
{
int i;
int sum = 0;
Node *s=head;
int len =strlen(str);
for (i = 0 ;i < len;i ++)
{
int id = str[i] - 'a';
if (s ->lt[id] == NULL)
{
return 0;
}
else
{
s = s ->lt[id];
sum = s ->sum;
}
}
return sum;
}
int main()
{
int n, m;
while(~scanf("%d%d",&n,&m))
{
cnt = 0;
head = &a[cnt++];
for (int i = 0;i < 26; i ++)
{
head ->lt[i] = NULL;
head ->sum = 0;
}
char t[20];
for(int i = 0; i < n; i ++)
{
scanf("%s",t);
strrev(t);
insert(t);
}
for (int i = 0; i < m; i ++)
{
scanf("%s",t);
strrev(t);
printf("%d\n",query(t));
}
}
return 0;
}
G: 玩叠骰子
Description
大家都玩过骰子吧,骰子一般都被用来赌博的工具,但是我们ACM的成员不一样。我们可以用骰子来编写出各种各样的题目,给广大爱好ACM的人锻炼思考问题的能力。看看骰子:
很熟悉吧o(∩_∩)o ~~~
废话不多说我们看题:现在给你n个骰子,把他们规范的叠起来,叠好后会有一些骰子的面被遮住,现在问你怎么叠没被遮住的那些面的点数和最大?
说明:叠的时候不能错开的叠,也就是说两个面要满满的叠住。并且叠在地上的那面也算被遮住的。Do you know?
上面这个叠法就不合法。
骰子:每个面点数分别是:1,2,3,4,5,6
1点的对面是6点,2的对面是5点,3的对面是4点,
各自的位置关系再看图。
Input
输入多组数据。
输入给定骰子的数目n,1<=n<=1000000。
Output
输出没被遮住的那些面的点数最大和。每个数据之间换行。
Sample Input
1 3 5 9
Sample Output
20 51 81 141
Hint
数学规律题,
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
/// n为1 时,答案为20
///当n不为1时,最小和的6*(n-1),
///最大和等于所有骰子的和减去最小和
int main()
{
int n;
while(~scanf("%d",&n))
{
if(n == 1)
{
printf("20\n");
continue;
}
printf("%d\n",21*n - 6*(n - 1));
}
}
H: 高级机密
Description
在很多情况下,我们需要对信息进行加密,特别是随着internet的高速发展,加密技术就显得尤为重要。
很早以前,罗马人为了在战争中传递信息,频繁地使用替换法进行加密。然而在计算机技术高速发展的今天,这种替换法显得不堪一击,因此密码研究人员正在试图寻找一种易于编码不易解码的编码规则。
有一种编码规则被称为RSA,是由美国麻省理工学院的三位教授发明的。这种编码规则是基于一种求密取模算法的:对于给出的三个正整数,a,b,c,计算a的b次方除以c的余数。
你的任务是编写一个程序,计算(a^b)mod(c)。
Input
输入含多组数据,以文本结束,每组数据占一行,分别输入3个正整数a、b、c,以空格间隔。
Output
输出占一行,输出(a^b)mod(c)的值。
Sample Input
2 6 11
Sample Output
9
边乘边取余
int main()
{
int n, m, mod;
while(~scanf("%d%d%d",&n,&m,&mod))
{
int sum = 1;
for(int i = 0; i < m; i ++)
{
sum *= n;
sum%= mod;
}
printf("%d\n",sum);
}
}
总结:
这场比赛题目很简单,但是在下午的时候,做了一个多小时,全是WA,然后剩下来的题目都是刚刚做了一下,说明还是有很多细节的问题没有去注意,导致一直WA,我还一度以为是OJ 的问题 233333333333333 蓝桥加油!