1. 程式人生 > >2010年臺州學院“科技活動月”程式設計爭霸賽

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 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 簡單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 body

Sample 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 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  藍橋加油!