ACM一些杂题2

Problem C - Laserbox

Time limit: 1 second

A laserbox is a game involving some optical equipment. The game board is a square n×n grid. On each grid point, a gadget called a right-turner can be placed and several such gadgets are included. Finally, there is a ruby laser, and if the laser is mounted at the bottom end of a column, the beam will be directed northwards through that column. Analogously, the laser beam may be directed southwards from the top of a column, eastwards from the start of a row or westwards from the end of the row.

The game starts with some right-turners being spread out on some grid points and the laser (switched off) being mounted somewhere along the border of the rectangle. The player then tries to deduce where the beam will emerge when the laser is switched on. The effect of a right-turner is to deflect the beam ninety degrees to the right, regardless of from which of the four directions it enters.

Your program must do exactly what the player is supposed to do.

Input

On the first line of the input is a single positive integer, telling the number of test cases to follow. The first line of each test case consists of two integers n r, where 1 ≤ n ≤ 50 is the size of the board and 1 ≤ r ≤ 50 the number of right-turners. The following r lines contain the coordinates x y of the right-turners. No two right-turners will have the same coordinates.

Finally, a line with two integers indicating the laser position follows. The bottom of column six is denoted by 6 0 and the start of row seven by 0 7. If the zeroes are replaced by n+1, the laser is placed at the top of column six and the end of row seven, respectively.

Output

For each test case, output one line containing the coordinates X Y of the beam as it leaves the board. The same rules as for the laser apply, so X may equal 0 or n+1 or else Y equal 0 or n+1. If the beam gets caught and does not leave the board, the output should be 0 0.

Sample Input

2
2 3
1 1
1 2
2 2
3 1
3 6
1 1
1 3
2 2
2 3
3 1
3 2
2 0

Sample Output

2 0
0 2
题意:光线从x,y射入,遇到right-turn会右转,问射出坐标

思路:模拟。

代码:

#include <stdio.h>
#include <string.h>

const int N = 55;
const int d[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

int t, n, r, x, y, g[N][N];

void init() {
	memset(g, 0, sizeof(g));
	scanf("%d%d", &n, &r);
	for (int i = 0; i < r; i++) {
		scanf("%d%d", &x, &y);
		g[x][y] = 1;
	}
	scanf("%d%d", &x, &y);
}

void solve() {
	int v;
	if (x == n + 1) v = 2;
	else if (x == 0) v = 0;
	else if (y == n + 1) v = 3;
	else v = 1;
	x += d[v][0]; y += d[v][1];
	while (x != 0 && x != n + 1 && y != 0 && y != n + 1) {
		if (g[x][y]) v = (v + 3) % 4;
		x += d[v][0]; y += d[v][1];
	}
	printf("%d %d\n", x, y);
}

int main() {
	scanf("%d", &t);
	while (t--) {
		init();
		solve();
	}
	return 0;
}

Problem F - Reduced ID Numbers

Time limit: 3 seconds

T. Chur teaches various groups of students at university U. Every U-student has a unique Student Identification Number (SIN). A SIN s is an integer in the range 0 ≤ s ≤ MaxSIN with MaxSIN = 106-1. T. Chur finds this range of SINs too large for identification within her groups. For each group, she wants to find the smallest positive integer m, such that within the group all SINs reduced modulo m are unique.

Input

On the first line of the input is a single positive integer N, telling the number of test cases (groups) to follow. Each case starts with one line containing the integer G (1 ≤ G ≤ 300): the number of students in the group. The following G lines each contain one SIN. The SINs within a group are distinct, though not necessarily sorted.

Output

For each test case, output one line containing the smallest modulus m, such that all SINs reduced modulo m are distinct.

Sample Input

2
1
124866
3
124866
111111
987651

Sample Output

1
8
题意:找一个能让所有数取模不相等的数字。

思路:暴力枚举

代码:

#include <stdio.h>
#include <string.h>

const int N = 305;
const int MAXN = 1000001;

int t, n, num[N], vis[MAXN];

int init() {
	scanf("%d", &n); int i = n, j;
	for (i = 0; i < n; i++) {
		scanf("%d", &num[i]);
	}
	while (i) {
		for (j = 0; j < n; j++) {
			if (vis[num[j] % i]) {
				for (int k = 0; k <= j; k++)
					vis[num[k] % i] = 0;
				break;
			}
			else vis[num[j] % i] = 1;
		}
		if (j == n) {
			for (int k = 0; k <= j; k++)
				vis[num[k] % i] = 0;
			return i;
		}
		i++;
	}
}

int main() {
	scanf("%d", &t);
	while (t--) {
		printf("%d\n", init());
	}
	return 0;
}

Description

Download as PDF

Frank N. Stein is a very conservative high-school teacher. He wants to take some of his students on an excursion, but he is afraid that some of them might become couples. While you can never exclude this possibility, he has made some rules that he thinks indicates a low probability two persons will become a couple:

  • Their height differs by more than 40 cm.
  • They are of the same sex.
  • Their preferred music style is different.
  • Their favourite sport is the same (they are likely to be fans of different teams and that would result in fighting).

So, for any two persons that he brings on the excursion, they must satisfy at least one of the requirements above. Help him find the maximum number of persons he can take, given their vital information.

Input

The first line of the input consists of an integer T ≤ 100 giving the number of test cases. The first line of each test case consists of an integer N ≤ 500 giving the number of pupils. Next there will be one line for each pupil consisting of four space-separated data items:

  • an integer h giving the height in cm;
  • a character 'F' for female or 'M' for male;
  • a string describing the preferred music style;
  • a string with the name of the favourite sport.

No string in the input will contain more than 100 characters, nor will any string contain any whitespace.

Output

For each test case in the input there should be one line with an integer giving the maximum number of eligible pupils.

Sample Input

2
4
35 M classicism programming
0 M baroque skiing
43 M baroque chess
30 F baroque soccer
8
27 M romance programming
194 F baroque programming
67 M baroque ping-pong
51 M classicism programming
80 M classicism Paintball
35 M baroque ping-pong
39 F romance ping-pong
110 M romance Paintball

Sample Output

3
7
题意:一些人,身高超过40,性别不同,喜欢音乐不同,喜欢运动相同的,满足其中一个条件就不能配对。问最多能带多少人,使得无人配对。

思路:二分图匹配,找出最大匹配对数,减掉即可。

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const int N = 505;
int t, n, fn, mn, g[N][N], vis[N], mh[N], ans;
struct Ma {
	int h;
	char sex[1];
	char music[105];
	char sport[105];
}male[N], female[N], mal;

bool judge(Ma a, Ma b) {
	if (abs(a.h - b.h) > 40 || strcmp(a.music, b.music) || strcmp(a.sport, b.sport) == 0)
		return false;
	return true;
}

void init() {
	fn = mn = 0;
	scanf("%d", &n);
	ans = n;
	while (n--) {
		scanf("%d%s%s%s", &mal.h, mal.sex, mal.music, mal.sport);
		if (mal.sex[0] == 'M') male[mn++] = mal;
		else female[fn++] = mal;
	}
	memset(g, 0, sizeof(g));
	memset(mh, -1, sizeof(mh));
	for (int i = 0; i < mn; i++)
		for (int j = 0; j < fn; j++)
			if (judge(male[i], female[j]))
				g[i][j] = 1;
}

bool find(int u) {
	for (int v = 0; v < fn; v++) {
		if (g[u][v] && !vis[v]) {
			vis[v] = 1;
			if (mh[v] == -1 || find(mh[v])) {
				mh[v] = u;
				return true;
			}
		}
	}
	return false;
}

int solve() {
	for (int i = 0; i < mn; i++) {
		memset(vis, 0, sizeof(vis));
		if (find(i))
			ans--;
	}
	return ans;
}
int main() {
	scanf("%d", &t);
	while (t--) {
		init();
		printf("%d\n", solve());
	}
	return 0;
}

Problem I - Up the Stairs

Time limit: 1 second

John is moving to the penthouse of a tall sky-scraper. He packed all his stuff in boxes and drove them to the entrance of the building on the ground floor. Unfortunately the elevator is out of order, so the boxes have to be moved up the stairs.

Luckily John has a lot of friends that want to help carrying his boxes up. They all walk the stairway at the same speed of 1 floor per minute, regardless of whether they carry a box or not. The stairway however is so narrow that two persons can't pass each other on it. Therefore they deciced to do the following: someone with a box in his hands is always moving up and someone empty-handed is always moving down. When two persons meet each other somewhere on the stairway, the lower one (with a box) hands it over to the higher one (without a box). (And then the lower one walks down again and the higher one walks up.) The box exchange is instantaneous. When someone is back on the ground floor, he picks up a box and starts walking up. When someone is at the penthouse, he drops the box and walks down again.

After a while the persons are scattered across the stairway, some of them with boxes in their hands and some without. There are still a number of boxes on the ground floor and John is wondering how much more time it will take before all the boxes are up. Help him to find out!

Input

One line with a positive number: the number of test cases. Then for each test case:

  • One line with three numbers N, F, B with 1 ≤ N,F ≤ 1000 and 1 ≤ B ≤ 1000000: the number of persons, the number of floors (0=ground floor, F=penthouse) and the number of boxes that are still on the ground floor.
  • N lines with two numbers fi and bi with 0 ≤ fi ≤ F and bi = 0 or bi = 1: the floors where the persons are initially and whether or not they have a box in their hands (1=box, 0=no box).

Output

One line with the amount of time (in minutes) it will take to get all the remaining boxes to the penthouse.

Sample Input

2
3 10 5
0 0
0 0
0 0
2 5 1
2 1
3 0

Sample Output

30
8
题意:n个人,f长的楼梯,m个物品在底楼,下面输入每个人在的位置和是否拿着物品(1为拿着,0为没有)。问最少时间把所有物品搬上去

思路:先算出所有人第一次搬运物品的时间,然后其实每个物品其余搬运时需要的时间为2 * f(一次来回)。这样只需要算第一次用时最长的,加上其余物品搬运时间即可。注意如果有出现物品不能正正好一人搬一次,那么就只需要算到第l大的人就可以了。因为比l大的人等于少搬一次。

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

const int N = 1005;
int t, n, f, m, cost[N];

void init() {
	scanf("%d%d%d", &n, &f, &m);
	int s, h;
	for (int i = 0; i < n; i++) {
		scanf("%d%d", &s, &h);
		if (h == 1) cost[i] = 3 * f - s;
		else cost[i] = f + s;
	}
	sort(cost, cost + n);
}

int solve() {
	int l = m % n;
	int time = m / n;
	if (l) return cost[l - 1] + time * f * 2;
	else return cost[n - 1] + (time - 1) * f * 2;
}

int main() {
	scanf("%d", &t);
	while (t--) {
		init();
		printf("%d\n", solve());
	}
	return 0;
}

Mo and Larry have devised a way of encrypting messages. They first decide secretly on the number of columns and write the message (letters only) down the columns, padding with extra random letters so as to make a rectangular array of letters. For example, if the message is “There’s no place like home on a snowy night” and there are five columns, Mo would write down

t o i o y
h p k n n
e l e a i
r a h s g
e c o n h
s e m o t
n l e w x

Note that Mo includes only letters and writes them all in lower case. In this example, Mo used the character ‘x’ to pad the message out to make a rectangle, although he could have used any letter. Mo then sends the message to Larry by writing the letters in each row, alternating left-to-right and right-to-left. So, the above would be encrypted as

toioynnkpheleaigshareconhtomesnlewx

Your job is to recover for Larry the original message (along with any extra padding letters) from the encrypted one.

Input

There will be multiple input sets. Input for each set will consist of two lines. The first line will contain an integer in the range 2...20 indicating the number of columns used. The next line is a string of up to 200 lower case letters. The last input set is followed by a line containing a single 0, indicating end of input.

Output

Each input set should generate one line of output, giving the original plaintext message, with no spaces.

Sample Input

5
toioynnkpheleaigshareconhtomesnlewx
3
ttyohhieneesiaabss
0

Sample Output

theresnoplacelikehomeonasnowynightx
thisistheeasyoneab
题意:水题不多说。

思路:字符串模拟输出即可。

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

const int N = 205;
int n;
char str[N], save[N][N];

void solve() {
	int len = strlen(str), i, j;
	for (i = 0; i < len / n; i++) {
		if (i % 2) {
			for (j = n - 1; j >= 0; j--)
				save[i][j] = str[i*n+n-1-j];
		}
		else {
			for (j = 0; j < n; j++)
				save[i][j] = str[i*n+j];
		}
	}
	for (i = 0; i < n; i++)
		for (j = 0; j < len / n; j++)
			printf("%c", save[j][i]);
	printf("\n");
}

int main() {
	while (~scanf("%d", &n) && n) {
		scanf("%s", str);
		solve();
	}
	return 0;
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值