灵动ICPC冬令营基础-1

A - Specialized Four-Digit Numbers

题目

Find and list all four-digit numbers in decimal notation that have the property that the sum of its four digits equals the sum of its digits when represented in hexadecimal (base 16) notation and also equals the sum of its digits when represented in duodecimal (base 12) notation.
For example, the number 2991 has the sum of (decimal) digits 2+9+9+1 = 21. Since 2991 = 11728 + 8144 + 9*12 + 3, its duodecimal representation is 189312, and these digits also sum up to 21. But in hexadecimal 2991 is BAF16, and 11+10+15 = 36, so 2991 should be rejected by your program.
The next number (2992), however, has digits that sum to 22 in all three representations (including BB016), so 2992 should be on the listed output. (We don’t want decimal numbers with fewer than four digits – excluding leading zeroes – so that 2992 is the first correct answer.)
Input
There is no input for this problem
Output
Your output is to be 2992 and all larger four-digit numbers that satisfy the requirements (in strictly increasing order), each on a separate line with no leading or trailing blanks, ending with a new-line character. There are to be no blank lines in the output. The first few lines of the output are shown below.
Sample Input

There is no input for this problem

Sample Output

2992
2993
2994
2995
2996
2997
2998
2999
...

解析

首先,设计一个函数Calc(base, n),计算和返回n转换成base进制后的各位数字之和。
然后,枚举[2992‥9999]内的每个数i:若Calc(10,i)== Calc(12, i)==Calc(16, i),则输出i。

代码

#include <stdio.h>
int Calc(base, n) {
	int sum=0;
	while(n) {
		sum+=n%base;
		n/=base;
	}
	return sum;
}
int main() {
	int i, j;
	for(i=2992;i<=9999;i++) {
		if(Calc(10,i)==Calc(12, i)&&Calc(12, i)==Calc(16, i)) printf("%d\n", i);
	}
	return 0;
}

B - Pig-Latin

题目

You have decided that PGP encryptation is not strong enough for your email. You have decided to
supplement it by first converting your clear text letter into Pig Latin before encrypting it with PGP.
Input and Output
You are to write a program that will take in an arbitrary number of lines of text and output it in Pig
Latin. Each line of text will contain one or more words. A “word” is defined as a consecutive sequence
of letters (upper and/or lower case). Words should be converted to Pig Latin according to the following
rules (non-words should be output exactly as they appear in the input):

  1. Words that begin with a vowel (a, e, i, o, or u, and the capital versions of these) should just
    have the string “ay” (not including the quotes) appended to it. For example, “apple” becomes
    “appleay”.
  2. Words that begin with a consonant (any letter than is not A, a, E, e, I, i, O, o, U or u) should
    have the first consonant removed and appended to the end of the word, and then appending “ay”
    as well. For example, “hello” becomes “ellohay”.
  3. Do not change the case of any letter.
    Sample Input
This is the input.

Sample Output

hisTay isay hetay inputay.

解析

首先,设计两个函数isab(char c)和vowel(char c),分别判断字符c是否是字母,以及是否是元音字母。
在主程序中,在输入文本后,根据试题描述中给出的规则进行处理:非字母的字符,直接输出;如果是单词(一个连续的字母序列),则如果单词是辅音字母开头,则把该辅音字母放到单词的最后;然后,所有的单词后加上“ay”。

代码

#include <stdio.h>
#define N  1e6 + 10
char s[N], t;
int isab(char c) {
	if(c>='a'&&c<='z'||c>='A'&&c<='Z') return 1;
	return 0;
}
int vowel(char c) {
	if(c=='a'||c=='A') return 1;
	if(c=='e'||c=='E') return 1;
	if(c=='i'||c=='I') return 1;
	if(c=='o'||c=='O') return 1;
	if(c=='u'||c=='U') return 1;
	return 0;
}
int main() {
	char c;
	int i;
	while(~scanf("%c", &c)) {
		if(isab(c)) {
			s[t++] = c;
		} else {
			if(t == 0) {
				printf("%c", c);
				continue;
			}
			if(vowel(s[0])) {
				for(i = 0; i < t; i++) {
					printf("%c", s[i]);
				}
				printf("ay%c", c);
			} else {
				for(i = 1; i < t; i++) {
					printf("%c", s[i]);
				}
				printf("%cay%c", s[0], c);
			}
			t = 0;
		}
	}
	return 0;
}

C - Tic Tac Toe

题目

Tic Tac Toe is a child’s game played on a 3 by 3 grid. One player, X, starts by placing an X at an unoccupied grid position. Then the other player, O, places an O at an unoccupied grid position. Play alternates between X and O until the grid is filled or one player’s symbols occupy an entire line (vertical, horizontal, or diagonal) in the grid.
We will denote the initial empty Tic Tac Toe grid with nine dots. Whenever X or O plays we fill in an X or an O in the appropriate position. The example below illustrates each grid configuration from the beginning to the end of a game in which X wins.
… X… X.O X.O X.O X.O X.O X.O

… … … … .O. .O. OO. OO.

… … … …X …X X.X X.X XXX

Your job is to read a grid and to determine whether or not it could possibly be part of a valid Tic Tac Toe game. That is, is there a series of plays that can yield this grid somewhere between the start and end of the game?
Input
The first line of input contains N, the number of test cases. 4N-1 lines follow, specifying N grid configurations separated by empty lines.
Output
For each case print “yes” or “no” on a line by itself, indicating whether or not the configuration could be part of a Tic Tac Toe game.
Sample Input

2
X.O
OO.
XXX

O.X
XX.
OOO

Sample Output

yes
no

解析

在这里插入图片描述

代码

#include <stdio.h>
char a[4][4];
int i, j;
int win(char c) {
	for(i=0;i<3;i++) {
		for(j=0;j<3&&a[i][j]==c;j++)
			if(j==2) return 1;
		for(j=0;j<3&&a[j][i]==c;j++)
			if(j==2) return 1;
	}
	for(i=0;i<3&&a[i][i]==c;i++)
		if(i==2) return 1;
	for(i=0;i<3&&a[i][2-i]==c;i++)
		if(i==2) return 1;
	return 0;
}
int main() {
	int n, o, x, t, h;
	while(scanf("%d", &n)!=EOF) {
		int t;
		h=n;
		while(h--) {
			t=1,o=0, x=0;
			for(i=0;i<3;i++) {
				scanf("%s", a[i]);
			}
			for(i=0;i<3;i++) {
				for(j=0;j<3;j++) {
					if(a[i][j]=='X') x++;
					else if(a[i][j]=='O') o++;
				}
			}
			if(x<o||x>=o+2) t=0;	
			if(win('X')&&win('O')) t=0;
			if(win('O')&&o!=x) t=0;
			if(win('X')&&o==x) t=0;
			if(t) printf("yes\n");
			else printf("no\n");
		}
	}
	return 0;
}

D - Factorial! You Must be Kidding!!!

题目

Arif has bought a super computer from Bongobazar. Bongobazar is a place in Dhaka where second hand goods are found in plenty. So the super computer bought by him is also second hand and has some bugs. One of the bugs is that the range of unsigned long integer of this computer for C/C++ compiler has changed. Now its new lower limit is 10000 and upper limit is 6227020800. Arif writes a program in C/C++ which determines the factorial of an integer. Factorial of an integer is defined recursively as:
factorial(0) = 1
factorial(n) = n ∗ factorial(n − 1).
Of course one can manipulate these expressions. For example, it can be written as
factorial(n) = n ∗ (n − 1) ∗ factorial(n − 2)
This definition can also be converted to an iterative one.
But Arif knows that his program will not behave rightly in the super computer. You are to write program which will simulate that changed behavior in a Normal Computer.
Input
The input file contains several lines of input. Each line contains a single integer n. No integer has more
than six digits. Input is terminated by end of file.
Output
For each line of input you should output a single line. This line will contain a single integer n! if the
value of n! fits within the unsigned long integer of Arif’s computer. Otherwise the line will contain one
of the following two words
Overflow! (When n! > 6227020800)
Underflow! (When n! < 10000)
Sample Input

2
10
100

Sample Output

Underflow!
3628800
Overflow!

解析

在这里插入图片描述
首先,离线计算F[i]=i!,8≤i≤13。
然后,对每个n,
如果8≤n≤13,则输出F[n];
如果(n>=14||(n<0&&(-n)%2= =1)),则输出"Overflow!";
如果(n<=7 || (n<0&&(-n)%2= =0)),则输出"Underflow!"。
在参考程序中,函数init()离线计算F[i]=i!,0≤i≤13。在函数中,循环变量i为局部变量;而F[i]则为全局变量。

代码

#include <stdio.h>
long long max=6227020800, min=10000;
#define N 13
long long F[N+1];
void init() {
	int i=1;
	F[0]=1;
	for(i=1;i<=N;i++) {
		F[i]=i*F[i-1];
	}
}
int main() {
	init();
	int n;
	int a[10];
	while(~scanf("%d", &n)) {
		if(n>N||n<0&&(-n)%2==1)
			printf("Overflow!\n");
		else if(F[n]<min||n<0&&(-n)%2==0)
			printf("Underflow!\n");
		else
			printf("%lld\n", F[n]);
	}
	return 0;
}

E - Function Run Fun

题目

We all love recursion! Don’t we?

Consider a three-parameter recursive function w(a, b, c):

if a <= 0 or b <= 0 or c <= 0, then w(a, b, c) returns:
1

if a > 20 or b > 20 or c > 20, then w(a, b, c) returns:
w(20, 20, 20)

if a < b and b < c, then w(a, b, c) returns:
w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c)

otherwise it returns:
w(a-1, b, c) + w(a-1, b-1, c) + w(a-1, b, c-1) - w(a-1, b-1, c-1)

This is an easy function to implement. The problem is, if implemented directly, for moderate values of a, b and c (for example, a = 15, b = 15, c = 15), the program takes hours to run because of the massive recursion.
Input
The input for your program will be a series of integer triples, one per line, until the end-of-file flag of -1 -1 -1. Using the above technique, you are to calculate w(a, b, c) efficiently and print the result.
Output
Print the value for w(a,b,c) for each triple.
Sample Input

1 1 1
2 2 2
10 4 6
50 50 50
-1 7 18
-1 -1 -1

Sample Output

w(1, 1, 1) = 2
w(2, 2, 2) = 4
w(10, 4, 6) = 523
w(50, 50, 50) = 1048576
w(-1, 7, 18) = 1

解析

对于取中间值的a、b和c,由于大量递归,程序运行非常耗时。所以,本题的递归函数计算采用记忆化递归进行计算,用一个三维的数组f来记忆递归的结果,f[a][b][c]用于记忆w(a, b, c)的返回值。

代码

#include <stdio.h>
#include <string.h>
#define N 20
#define M 10008
int f[N+1][N+1][N+1];
int a[M], b[M], c[M], i;
int w(int a, int b, int c) {
	if(a<=0||b<=0||c<=0) return 1;
	else if(a>N||b>N||c>N) return w(N,N,N);
	else if(f[a][b][c]) return f[a][b][c];
	else if(a<b&&b<c) return f[a][b][c]=w(a, b, c-1)+w(a, b-1, c-1)- w(a, b-1, c);
	else return f[a][b][c]=w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1);
}
int main() {
	memset(f,0,sizeof(f));
	for(i=0;a[i]!=-1||b[i]!=-1||c[i]!=-1;i++) {
		scanf("%d%d%d", &a[i], &b[i], &c[i]);
		if(a[i]==-1&&b[i]==-1&&c[i]==-1) break;
	}
	for(i=0;a[i]!=-1||b[i]!=-1||c[i]!=-1;i++) {
		printf("w(%d, %d, %d) = %d\n", a[i], b[i], c[i], w(a[i],b[i],c[i]));
	}
	return 0;
}

F - Simple Addition

题目

Lets define a simple recursive function F(n), where
在这里插入图片描述

Lets define another function S(p, q),
在这里插入图片描述

In this problem you have to Calculate S(p, q) on given value of p and q.
Input
The input file contains several lines of inputs. Each line contains two non negative integers p and q
(p ≤ q) separated by a single space. p and q will fit in 32 bit signed integer. In put is terminated by a
line which contains two negative integers. This line should not be processed.
Output
For each set of input print a single line of the value of S(p, q).
Sample Input

1 10
10 20
30 40
-1 -1

Sample Output

46
48
52

解析

根据递归函数F(n)的定义给出递归函数。因为p和q是32位有符号整数,S(p, q)的值可能会超出32位有符号整数,所以本题的变量类型定义为long long int,即64位有符号整数。
在这里插入图片描述
本题递归算法:
每一轮求出[p, q]区间内数字的个位数的和,并计入总和;再将[p, q]区间内个位数为0的数除以10,产生新区间,进入下一轮,再求新区间内数字的个位数的和,并计入总和,而个位数为0的数除以10,产生新区间;以此类推;直到[p, q]区间内的数只有个位数。
例如,求S(2, 53),将范围划分为3个区间:[2, 9],[10, 50]和[51,53]。
对于第1个区间[2, 9],个位数之和2+3+4+……+9=44;对于第2个区间[10, 50],个位数之和(1+2+……+9)4= 454 = 180;对于第3个区间[51, 53],个位数之和1+2+3 = 6。所以,第一轮,个位数的总和为44+180+6 = 230。
在[10, 50]中,10, 20, 30, 40和50的个位数是0,将这些数除以10后得1, 2, 3, 4, 5,产生新区间[1, 5];进入第二轮,区间[1, 5]中的数只有个位数,个位数之和1+2+3+4+5=15。
最后,两轮结果相加,得S(2, 53)=230+15=245。

代码

#include <stdio.h>
#define ll long long
ll ans;
ll f(ll x) {
	if(x==0) return 0;
	else if(x%10>0) return x%10;
	else return f(x/10);
}
void solve(ll l, ll r) {
	int i;
	ans;
	if(r-l<9) {
		for(i=l;i<=r;i++)
			ans+=f(i);
		return;
	}
	while(l%10) {
		ans+=f(l);
		l++;
	}
	while(r%10) {
		ans+=f(r);
		r--;
	}
	ans+=45*(r-l)/10;
	solve(l/10,r/10);
}
int main() {
	int a, b;
	while(scanf("%d%d", &a, &b)!=EOF) {
		if(a==-1&&b==-1) return 0;
		else ans=0,solve(a,b), printf("%lld\n", ans);
	}
	return 0;
}

G - A Contesting Decision

题目

Judging a programming contest is hard work, with demanding contestants, tedious decisions,and monotonous work. Not to mention the nutritional problems of spending 12 hours with only donuts, pizza, and soda for food. Still, it can be a lot of fun.
Software that automates the judging process is a great help, but the notorious unreliability of some contest software makes people wish that something better were available. You are part of a group trying to develop better, open source, contest management software, based on the principle of modular design.
Your component is to be used for calculating the scores of programming contest teams and determining a winner. You will be given the results from several teams and must determine the winner.
Scoring
There are two components to a team’s score. The first is the number of problems solved. The second is penalty points, which reflects the amount of time and incorrect submissions made before the problem is solved. For each problem solved correctly, penalty points are charged equal to the time at which the problem was solved plus 20 minutes for each incorrect submission. No penalty points are added for problems that are never solved.
So if a team solved problem one on their second submission at twenty minutes, they are charged 40 penalty points. If they submit problem 2 three times, but do not solve it, they are charged no penalty points. If they submit problem 3 once and solve it at 120 minutes, they are charged 120 penalty points. Their total score is two problems solved with 160 penalty points.
The winner is the team that solves the most problems. If teams tie for solving the most problems,then the winner is the team with the fewest penalty points.
Input
For the programming contest your program is judging, there are four problems. You are guaranteed that the input will not result in a tie between teams after counting penalty points.
Line 1 < nTeams >
Line 2 - n+1 < Name > < p1Sub > < p1Time > < p2Sub > < p2Time > … < p4Time >
The first element on the line is the team name, which contains no whitespace.Following that, for each of the four problems, is the number of times the team submitted a run for that problem and the time at which it was solved correctly (both integers). If a team did not solve a problem, the time will be zero. The number of submissions will be at least one if the problem was solved.
Output
The output consists of a single line listing the name of the team that won, the number of problems they solved, and their penalty points.
Sample Input

4
Stars 2 20 5 0 4 190 3 220
Rockets 5 180 1 0 2 0 3 100
Penguins 1 15 3 120 1 300 4 0
Marsupials 9 0 3 100 2 220 3 80

Sample Output

Penguins 3 475

解析

本题的参考程序用结构体表示参赛队信息,结构体Team中包含参赛队名、4道题提交次数、4道题解题时间、解题数,以及总罚时。所有的参赛队则表示为一个结构体数组team。
设冠军队的队名为wname,解题数为wsol,罚时为wpt。
首先,依次读入每个队的队名name和4道题的提交次数subi,解题时间timei:并计算每个队的解题数和总罚时。
然后,依次处理完n个参赛队的信息,若当前队解题数最多,或虽同为目前最高解题数但罚时最少((team[i].num>wsol) ||(team[i].num==wsol && team[i].time<wpt)),则将当前队暂设为冠军队,记下队名、解题数和罚时。
在处理完n个参赛队的信息后,wname、wsol和wpt就是问题的解。

代码

#include <stdio.h>
#include <string.h>
#define N 1000
typedef struct Team{
	char name[30];
	int subi[4];
	int  timei[4];
	int num, time;
}Team;
int main() {
	int n, i, j;
	Team team[N];
	char wname[30];
	int wsol;
	int wpt;
	scanf("%d", &n);
	memset(team,0,sizeof(0));
	for(i=0;i<n;i++) {
		scanf("%s", &team[i].name);
		for(j=0;j<4;j++) {
			scanf("%d%d", &team[i].subi[j], &team[i].timei[j]);
		}
		team[i].num=0;
		team[i].time=0;
		for(j=0;j<4;j++) {
			if(team[i].timei[j]>0) {
				team[i].num+=1;
				team[i].time+=team[i].timei[j]+(team[i].subi[j]-1)*20;
			}
		}
	}
	wsol=-1;
	wpt=1000000000;
	for(i=0;i<n;i++) {
		if((team[i].num>wsol)||(team[i].num==wsol&&team[i].time<wpt)) {
			wsol=team[i].num;
			wpt=team[i].time;
			strcpy(wname, team[i].name);
		}
	}
	printf("%s %d %d", wname, wsol, wpt);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值