2010年臺州學院“科技活動月”程式設計爭霸賽
因為最近一直有新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)[email protected]Sample Output
(2)Gdfg7&fd (3)Dguyuy*fd% (5)[email protected]就是素數的判斷了,而且還是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 0Sample 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 8Sample Output
29 簡單DP#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 bodySample Output
2 2 2 字典樹,這裡求的是字尾,其實可以先把字串倒轉過來處理,用到一個函式strrev,我不知道這個函式的處理時間快不快,但是這裡並沒有超時,畢竟單字串最長不過10,時間是100+ms#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 9Sample Output
20 51 81 141Hint
注意:所有骰子必須緊靠在一起。數學規律題,
#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 11Sample 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 藍橋加油!