搜档网
当前位置:搜档网 › ACM新生赛题目解题报告2

ACM新生赛题目解题报告2

ACM新生赛题目解题报告2
ACM新生赛题目解题报告2

Hosted by 计算机与信息科学系

解题报告

2012.5.19

12:00~17:00

本题册总共有10道题目,页数共有39页。

注意事项

1、比赛网址是:https://www.sodocs.net/doc/995643207.html,。

2、可以带一切纸质材料,严禁携带U盘等电子类产品。

3、杜绝网上搜索资料和互相抄袭,如有发现,上报学校处分。

4、本测试系统采用的是window平台的服务器,int类型为4

个字节,__int64为8个字节,8个字节的输出格式为

printf(“%I64d\n”,n);

5、有问题可以举手找志愿者。

6、比赛结束将分发答案参考程序。

1、Be Good at Guassing

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem Description

Give you many positive integer N (N<=23),for each N, just output N*(N+1)/2 integers in a single line, separated by space. (Don't ask me why.)For each N, the output line contains integers from 1 to N, and each just once. Again, do not ask me why, thank you. I'm so busy. But I can tell you a secret, the output has relationship with number triangle. As:(N=3)

1

2 6

3 4 5

See the sample for more information.

Input

Many lines, each line contains a positive integer N (N<=23).

3

4

2

6

Sample Output

1 2 6 3 4 5

1 2 9 3 10 8 4 5 6 7

1 2 3

1 2 15 3 16 14 4 17 21 13 5 18 19 20 12 6 7 8 9 10 11 解题代码

#include

using namespace std;

#include

#include

#include

#include

const int maxN = 24;

int tri[maxN][maxN];

int main()

{

int N,value,row,col,dir,i,j;

while(cin>>N)

{

memset(tri,0,sizeof(tri));

row=col=1;

for(value=1;value<=N;++value)

tri[row++][col]=value;

row=N,col=2;

for(value=N+1;value<=2*N-1;++value) tri[row][col++]=value;

row=N-1,col=N-1;

for(value=2*N;value<=3*N-3;++value) tri[row--][col--]=value;

row=2,col=2;

value=3*N-2;

dir=1;

while(value<=N*(N+1)/2)

{

if(1==dir)/*down one line*/

{

if((0==tri[row+1][col]))

tri[++row][col]=value;

else

{

dir=2;

tri[row][++col]=value;

}

}

else if(2==dir)/*right one line*/ {

if((0==tri[row][col+1]))

tri[row][++col]=value;

else

{

dir=3;

tri[--row][--col]=value;

}

}

else

{

if((0==tri[row-1][col-1]))

tri[--row][--col]=value;

else

{

dir=1;

tri[++row][col]=value;

}

}

++value;

}

for(row=1;row<=N;++row)

{

for(col=1;col<=row;++col)

{

cout<

if(!(row==N&&col==row))

cout<<" ";

}

}

cout<

}

return 0;

}

2、工院宅男

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem Description

男女比例严重失调的工院向来不乏宅男,Jim做为茫茫一员,每天过着三点一线的生活,宿舍、饭店、教室。为了节省时间Jim觉得应该找一个离宿舍和教室最近的饭店,没必须浪费这么多时间在这条线上(神一般的宅男)。现在给你一张地图来帮Jim找出这个饭店,在这张地图中Jim可以往上、下、左、右四个方向走,且花费一个单位的时间。输入只包含一个宿舍、一个教室,饭店可以多个。

Input

第一行输入一个正整数T,表示共有T组测试项。

每组先输入两个整数n、m(2<=m、n<=200)表示地图的规模。

接下来是n行,每行m个字符:

‘S’ 表示宿舍

‘F’ 饭店

‘J’ 教室

‘#’ 障碍

‘.’ 路

Output

每一项输出Jim所要花的最少时间。结果保证可以找到一个饭店。

Sample Input

3

4 4

J.#F

....

..#S

. F..

4 4

J.#F

....

.#..

F#.S

5 5

J..F.

.....

.#...

F..S.

#.#.#

Sample Output

7

8

6

解题报告

两遍广度优先搜索

#include #include using namespace std; struct node{

int i,j;

int time;

};

int array[250][250];

int direction[4][2]={{0,-1},{0,1},{1,0},{-1,0}}; char map[250][250];

bool mark[250][250];

int n,m;

void bfs(int x,int y){

queue q;

node d,p;

p.i=x;

p.j=y;

p.time=0;

mark[x][y]=true;

q.push(p);

while(!q.empty()){

d=q.front();

q.pop();

if('F'==map[d.i][d.j]){

array[d.i][d.j]+=d.time;

}

for(int i=0;i<4;i++){

p.i=d.i+direction[i][0];

p.j=d.j+direction[i][1];

if( p.i>=0&&p.i=0&&p.j

&&false==mark[p.i][p.j]

&&'#'!=map[p.i][p.j]){

mark[p.i][p.j]=true;

p.time=d.time+1;

q.push(p);

}

}

}

}

int main(){

int T,m_i,m_j;

int y_i,y_j;

scanf("%d",&T);

while(T--){

cin>>n>>m;

for(int i=0;i

for(int j=0;j

cin>>map[i][j];

if('J'==map[i][j]){

y_i=i;

y_j=j;

}

else if('S'==map[i][j]){

m_i=i;

m_j=j;

}

}

memset(array,0,sizeof(array)); memset(mark,false,sizeof(mark));

bfs(m_i,m_j);

memset(mark,false,sizeof(mark));

bfs(y_i,y_j);

int min=999999999;

for(int i=0;i

for(int j=0;j

if(array[i][j]!=0&&min>array[i][j]){ min=array[i][j];

}

}}

cout<

} return 0; }

3、Fantasy character game

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem Description

A string and the string operations are given. Please deal with the string according to the operation orderly, and tell me what the final string is.

Operations:

Step 1: Reverse the order of the string from the first character to the last, such as change ABCDE into EDCBA.

Step 2: Pick up the odd digit letters of the string together and put it in the front of the string, such as change ABCDE into ACEBD.

Step 3: For each letter of the string, if the letter is in A-M plus 13, if not, minus 13, such as change A into N and O into B.

Step 4: Map each character in the string, A-Z respectively corresponding to QWERTYUIOPASDFGHJKLZXCVBNM.

Step 5: Split the string into two substrings, the length of the first half substring is L/2, and the second is (L+1)/2 long, then put the second substring before the first one, for example: make ABCDE into CDEAB or ABCDEF into DEFABC.

Step 6: Split the string into two substrings, the length of the first half substring is L/2, and the second is (L+1)/2 long, then make each substring do Step 1 and then connect them up. such as make ABCDE into

BAEDC or ABCDEF into CBAFED.

Input

An integer T means T cases. T<=100,The lenth of the string<=100。

Following T lines, each line contains one string, make up by character 'A' to 'Z'. The length of every string is less then 10086.

Output

Print one string to each case.

Sample Input

2

ABCDE

UPFSVVJT

Sample Output

Case 1:

JFHKG

Case 2:

ILOVEYOU

解题报告

简单的字符串模拟题

#include

#include

char s1[10086];

char s2[10086];

char

map[27]={'Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X',

'C','V','B','N','M'};

int main()

{

int cas,CAS;

int l,i;

scanf("%d",&CAS);gets(s2);

for(cas=1;cas<=CAS;cas++)

{

gets(s1);

memset(s2,0,sizeof(s2));

l=strlen(s1);

for(i=0;i

s2[l-i-1]=s1[i];

for(i=0;i

s1[i/2]=s2[i];

for(i=1;i

s1[(l+i-1)/2+(l%2)]=s2[i];

for(i=0;i

if(s1[i]>'M') s1[i]-=13;

else s1[i]+=13;

for(i=0;i

s1[i]=map[s1[i]-'A'];

if(l&1)

{ s2[l-1]=s1[l-1];

for(i=0;i

s2[l-i-2]=s1[i];

}

else

{

for(i=0;i

s2[l-i-1]=s1[i];

}

printf("Case %d:\n",cas);

puts(s2);

}

return 0;

}

4、环形渠道

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem Description

一个环形渠道,被n个挡板分为n块区域,每块区块含M1、M2、M3……Mn 大小的水量,现在要求拆掉最少的挡板使各个区域的水量相等。比如环形渠道被6块挡板分为10 、3、5、4、1、1的水量,那么只要拆除3块挡板即可(分别拆除3和5、1和1、1和10之间的挡板)

Input

第一行输入一个正整数数T,表示共有T组测试数据。

接下来是T行

每行的第一个数为整数n,表示水池分为n块区块,之后输入n个正整数,分别表示每个区域的水量。

Output

输出每组数据至少要拆除要多少块挡板,每组一行。

Sample Input

3

6 10 3 5 4 1 1

4 4 4 3 3

8 2 1 1 2 2 1 1 6

Sample Output

3

2

5

解题报告

这题不要想太多,直接暴力两重循环,直到找到各个水池相等为止。#include

#include

#include

#include

#include

#define eps 1e-8

using namespace std;

int main()

{ int t;

int n;

int tank[210];

cin>>t;

while (t--)

{

cin>>n;

int i;

double sum = 0;

for (i = 0; i < n; i++)

{

cin>>tank[i];

sum += tank[i];

}

double avg = sum/n;

int mmin = n;

int cnt = 0;

double temp = 0;

int t_min = 0;

int j;

for (i = 0; i < n; i++)

{

cnt = 1;

temp = 0;

t_min = 0;

for (j = 0; j < n; j++)

{

temp += tank[(i + j) % n];

if (abs(temp / cnt - avg) < eps)

{

t_min += cnt - 1;

temp = 0;

cnt = 1;

相关主题