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)tttthdsf@

Sample Output

 
     
(2)Gdfg7&fd (3)Dguyuy*fd% (5)tttthdsf@

    就是素数的判断了,而且还是200以内的素数,还有需要注意的是取的是括号里面的数,一开始我就直接从tt[1]到tt[4]里面判断数字了,有可能是(2)5sflksfksld类似这样的

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
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=

Output

输出搜救狗最多能救多少受灾的人的数量。

Sample Input

 
    
4 7 #p.d#p# #####.# d.....# ######p 0 0

Sample Output

 
    
2

    简单的搜索,注意从p位置搜d 比较好,不然容易超时

    

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
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 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 走的时候从通道入口进入从出口出去,并且通道入口一直在最左上角,通道出口一直在最右下角。

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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
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  蓝桥加油!


你可能感兴趣的:(ACM,-,题集)