您的位置:首页 > 产品设计 > UI/UE

2016 UESTC ACM Summer Training Team Selection (2)解题报告

2016-05-07 18:04 671 查看
总体来说,个人英语水平还太蹩脚,此次大部分时间都花在理解题意上了,而且到最后有些题目的意思还是不理解,orz...

链接→2016
UESTC ACM Summer Training Team Selection (2)


 Problem A Popular Vote

Accept: 0    Submit: 0

Time Limit: 2000 mSec



 Problem Description

In an election with more than two candidates, it is often the case that the winner (the candidate receiving the most votes) receives less than the majority of the votes. Given the results of an election, can you determine the winner, and whether the winner
received more than half of the votes?





 Input

       The first line of input contains a single positive integer T ≤ 500 indicating the number of test cases. The first line of each test case also contains a single positive integer n indicating the number of candidates in the election. This is followed by
n lines, with the ith line containing a single nonnegative integer indicating the number of votes candidate i received.

There are at least 2 and no more than 10 candidates in each case, and each candidate will not receive more than 50 000 votes. There will be at least one vote cast in each election.



 Output

Provide a line of output for each test case. If the winner receives more than half of the votes, print the phrase

majority winner followed by the candidate number of the winner. If the winner does not receive

more than half of the votes, print the phrase minority winner followed by the candidate number of the

winner. If a winner cannot be determined because no single candidate has more vote than others, print the

phrase no winner. The candidate numbers in each case are 1, 2, . . . , n.



 Sample Input

4

3

10

21

10

3

20

10

10

3

10

10

10

4

15

15

15

45



 Sample Output

majority winner 2

minority winner 1

no winner

minority winner 4

解题思路:给你n位候选人获得的选票,问几号候选人是获胜者,如果存在多位获得最多选票的人,输出"no winner";若获得最多选票的人票数超过总票数的一半,输出"majority winner x",x表示候选人的编号(从1开始);否则,输出"minority winner x"
简单题,用数组记录每种票数出现的次数,并用ans记录票数的最大值即可

题目链接→1367 Popular Vote

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 50005;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
int s
;
int main()
{
int t,ans,i,n,x,c,sum;
scanf("%d",&t);
while(t--)
{
memset(s,0,sizeof(s));
ans=sum=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&x);
sum+=x;
s[x]++;
if(ans<x)
ans=x,c=i;
}
if(s[ans]>1)
puts("no winner");
else if(ans>sum/2)
printf("majority winner %d\n",c);
else
printf("minority winner %d\n",c);
}
return 0;
}



 Problem B Flipping Cards

Accept: 0    Submit: 0

Time Limit: 5000 mSec



 Problem Description

Mike and his young daughter Jesse are playing a new card game meant

for kids. The rules are quite simple, each player is dealt a hand of cards.

Each card has one picture on each side. They take turns playing cards

and the first one to run out of cards is the winner.



A player’s turn consists of picking a subset of cards from their hand and

laying them on the table. The only rule is that the cards must be placed

on the table such that no two cards are showing the same picture.

Mike thought this was a very appropriate game to play with his kid because of the simple rules. Mike also

liked this game because finding the best strategy is an algorithmically interesting challenge!

Help Mike determine if he can play his entire hand on his first round.



 Input

The first line of the input contains a single positive integer T (T ≤ 10) indicating the number of test cases. Each test case begins with a single integer n denoting the number of cards in Mike’s hand. Here 1 ≤ n ≤ 50 000. Following this are n lines, each describing
a card in Mike’s hand. The pictures on the cards are represented by integers. The ith card is given by two integers pi , qi where 1 ≤ pi , qi ≤ 2n.



 Output

For each test case you should output a single line with the word possible if it ispossible for Mike to play his entire hand in one turn, orimpossible if Mike cannot play his entire hand in one turn.



 Sample Input

3

3

1 2

1 3

2 3

3

1 2

1 2

1 2

1

1 1



 Sample Output

possible

impossible

possible

解题思路:给你n组牌,每组两张,问从n组牌中每组取出一张,是否可以做到n张牌均不相同,若可以,输出"possible";否则,输出"impossible"

说实话,一开始想过很多种方法,但是总是没办法考虑全,后来还是同学给的启发

首先,我们给每组的两张牌之间连一条边,那此题就转变成了求取n条边和m(>=n均可)个点

这时,我们就想到了连通分量,对于每个连通分量,只要满足点的个数大于等于边的个数,就是有解的

也就是说若存在一个连通分量,它的边数大于点数,那就做不到n张牌均不相同,因为n条边是必取的,能取的点太少就意味着存在那么一组牌,我没法取

而判连通分量,我们可以采用并查集来解决

放上几组数据供以测试

Input

3

2 1

3 1

2 3

Output

possible

Input

5

1 1

1 1

2 3

4 5

6 7

Output

impossible

Input

4

1 2

1 1

2 2

3 4

Output

impossible

Input

3

1 2

1 3

1 4

Output

possible

Input

4

1 1

1 2

2 3

3 3

Output

impossible

Input

6

2 1

3 1

2 3

5 6

5 7

6 7

Output

possible

题目链接→1369 Flipping Cards

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 50005;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
int s[2*N],e[2*N],m[2*N],p
,q
;
int fun(int x)
{
if(s[x]!=x)
s[x]=fun(s[x]);
return s[x];
}
int main()
{
int t,n,i,x,y,k;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n+n;i++)
s[i]=i,e[i]=m[i]=0;
for(i=0;i<n;i++)
{
scanf("%d%d",&p[i],&q[i]);
x=fun(p[i]);
y=fun(q[i]);
s[x]=y;
}
for(i=0;i<n;i++)
e[fun(p[i])]++;
for(i=1;i<=n+n;i++)
m[fun(i)]++;
for(i=1;i<=n+n;i++)
{
k=fun(i);
if(e[k]>m[k])
break;
}
if(i<=n+n)
puts("impossible");
else
puts("possible");
}
return 0;
}



 Problem D Scaling Recipes

Accept: 0    Submit: 0

Time Limit: 8000 mSec



 Problem Description

A recipe is a list of ingredients and a set of instructions to prepare a dish. It is often written for a particular number of portions. If you have a recipe for 4 portions and you want to make 6 portions, it turns out that simply multiplying the amounts for each
ingredient by 1.5 is often wrong! The reason is that the original recipe may have been rounded to the nearest teaspoon, gram, etc., and the rounding errors magnify when a recipe is scaled.

Some recipes are specifically written to ease the task of scaling. These recipes are developed using “Baker’s percentages.” Each ingredient is listed not only by weight (in grams), but also as a percentage relative to the “main ingredient.” The main ingredient
will always have a 100% Baker’s percentage. Note that the sum of the Baker’s percentages from all ingredients is greater than 100%, and that the Baker’s percentages of some ingredients may exceed 100%.



Table 1: Example Recipe
Ingredient Weight (g) Percentage (%)
Olive Oil

Garlic
Beef

Onions

Raisins

Bouillon

50.9

12.0
453.6 

 1134.0

82.5

10.0

11.2

2.7
 100.0

 250.0

18.2

2.2
To scale a recipe:
1. determine the scaling factor by dividing the number of desired portions by the number of portions for which the recipe is written;
2. multiply the weight of the main ingredient with a 100% Baker’s percentage by the scaling factor. This is the scaled weight of the main ingredient;
3. calculate the scaled weight of every other ingredient by multiplying its Baker’s percentage by the scaled weight of the main ingredient.



 Input

The first line of input specifies a positive integer T ≤ 1000, consisting of the cases to follow. Each case

starts with a line with three integers R, P, and D: 1 ≤ R ≤ 20 is the number of ingredients, 1 ≤ P ≤ 12 is

the number of portions for which the recipe is written, and 1 ≤ D ≤ 1000 is the number of desired portions.

Each of the next R lines is of the form
<name> <weight> <percentage>

where <name> is the name of the ingredient (an alphabetic string of up to 20 characters with no embedded

spaces), <weight> is the weight in grams for that ingredient, and <percentage> is its Baker’s percentage.

Both <weight> and <percentage> are floating-point numbers with exactly one digit after the

decimal point. Each recipe will only have one ingredient with a Baker’s percentage of 100%.



 Output

For each case, print Recipe # followed by a space and the appropriate case number (see sample output

below). This is followed by the list of ingredients and their scaled weights in grams. The name of the

ingredient and its weight should be separated by a single space. Each ingredient is listed on its own line, in

the same order as in the input. After each case, print a line of 40 dashes (’-’). Answers within 0.1g of the

correct result are acceptable.



 Sample Input

2

6 4 20

oliveoil 50.9 11.2

garlic 12.0 2.7

beef 453.6 100.0

onions 1134.0 250.0

raisins 82.5 18.2

bouillon 10.0 2.2

4 5 8

Milk 265.0 93.0

SodiumCitrate 11.0 4.0

WhiteCheddar 285.0 100.0

DryMacaroni 240.0 84.0



 Sample Output

Recipe # 1

oliveoil 254.0

garlic 61.2

beef 2268.0

onions 5670.0

raisins 412.8

bouillon 49.9

----------------------------------------

Recipe # 2

Milk 424.1

SodiumCitrate 18.2

WhiteCheddar 456.0

DryMacaroni 383.0

----------------------------------------

解题思路:此题题目倒是很长,不过有用的就To scale a recipe里的三点,首先根据输入的P和D计算出缩放倍数factor=D/P,然后找到percentage为100.0的食材,将它的weight*factor即可得到main ingredient的scaled weights in grams,然后循环一遍,根据其他食材的percentage与main
ingredient的percentage的比例计算得到其他食材的scaled weights in grams

题目链接→1376 Scaling Recipes

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 25;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
struct recipe
{
char name
;
double weight,percentage,ans;
}s
;
int main()
{
int t,r,p,d,i,k,c=1;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&r,&p,&d);
double factor=d*1.0/p;
for(i=0;i<r;i++)
{
scanf("%s%lf%lf",s[i].name,&s[i].weight,&s[i].percentage);
if(s[i].percentage==100.0)
{
k=i;
s[i].ans=s[i].weight*factor;
}
}
printf("Recipe # %d\n",c++);
for(i=0;i<r;i++)
{
if(i!=k)
s[i].ans=s[k].ans*(s[i].percentage/100.0);
printf("%s %.1f\n",s[i].name,s[i].ans);
}
for(i=0;i<40;i++)
printf("-");
puts("");
}
return 0;
}



 Problem E Space Junk

Accept: 0    Submit: 0

Time Limit: 4000 mSec



 Problem Description

According to NASA’s web page, there are more than 500 000 pieces of “space

junk” that are tracked. Care must be taken in mission planning so satellites

and other spacecrafts do not collide with these pieces of space junk.

For this problem, we will consider the simplified case in which both the spacecraft

and the space junk can be modelled as spheres that are travelling in a

straight line. Given the current locations of the two spheres as well as their

velocities, when would they collide in the future, if ever?





 Input

The first line of input contains a single positive integer T ≤ 500 indicating the number of test cases. Each

test case is specified by two lines. The first line specifies the sphere representing the spacecraft, while the

second line specifies the sphere representing the space junk. Each sphere is specified by the seven integers

x, y, z, r, vx, vy, vz. The center of the sphere is currently located at (x, y, z), the radius of the sphere is r,

and the sphere is travelling along the direction specified by the vector (vx, vy, vz). If the vector is (0, 0, 0),

the sphere is stationary.

The absolute value of all integers are at most 100, and r is positive. All coordinates and radius are measured

in meters, and the velocities are measured in meters/second.

You may assume that the two spheres do not touch each other initially.



 Output

For each test case, output a line containing the time (in seconds) at which the spacecraft first collides with

the space junk. If they never collide, print No collision instead. Answers within 0.01 of the correct

result are acceptable.



 Sample Input

3

10 3 -10 5 -9 3 -8

2 0 0 6 -4 3 -10

-7 5 0 3 -1 0 3

10 7 -6 6 -2 0 4

-4 -1 0 3 -1 -5 -6

2 1 8 6 4 0 -1



 Sample Output

0.492

8.628

No collision

解题思路:给你两个球体的三维坐标,半径以及它们的方向向量(球体沿方向向量的方向作直线运动),问两个球体会不会发生碰撞,若会,给出发生碰撞的时间;若不会,则输出"No collision"

相信大家拿到这题的时候思路很清晰,要知道两球体是否会发生碰撞,我们只需找到它们俩之间的最小球心距是否小于等于俩球体半径之和即可

那么如何求这个最小球心距呢?假设球心距为d,移动时间为t

首先,我们可以分别得到俩球体的参数方程(因为x,y,z已被占用,我们暂时假设横坐标为a,纵坐标为b,竖坐标为c)

球体1的参数方程:



球体2的参数方程:



那么俩球体的球心距d(划红线部分用a代替,划蓝线部分用b代替,划紫线部分用c代替):



一元二次方程?但是要小心了,这里我们需要特判a=0的情况,这时b也为0,球心距的平方是个定值c,因为题目说俩球体一开始没有接触,那么平行运动的俩球体必然不会发生碰撞

剩下的就是一元二次方程的情况了

当且仅当t=-b/(2*a)时,d取得最小值,但要注意,若t<0,说明俩球体之间的距离一直在增大

判断d与r1+r2之间的关系,若d<=r1+r2,两者会发生碰撞,但此时的时间不一定是最早发生碰撞的时间,这时要求解方程a*t*t+b*t+c=r1+r2的最小非负解

此题说简单也简单,说难也难,主要是看我们能不能推导出公式,只要能推导出公式,剩下的就是细节问题

题目链接→1373 Space Junk

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 100005;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
int main()
{
int T,x1,y1,z1,r1,vx1,vy1,vz1,x2,y2,z2,r2,vx2,vy2,vz2,a,b,c;
double t,d,ans;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d%d%d%d",&x1,&y1,&z1,&r1,&vx1,&vy1,&vz1);
scanf("%d%d%d%d%d%d%d",&x2,&y2,&z2,&r2,&vx2,&vy2,&vz2);
b=2*((x2-x1)*(vx2-vx1)+(y2-y1)*(vy2-vy1)+(z2-z1)*(vz2-vz1));
a=(vx2-vx1)*(vx2-vx1)+(vy2-vy1)*(vy2-vy1)+(vz2-vz1)*(vz2-vz1);
c=(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1);
if(!a)
{
puts("No collision");
continue;
}
t=max(1.0*(-b)/2/a,0.0);
d=a*t*t+b*t+c;
if(d<=(r1+r2)*(r1+r2)+exp)//不考虑精度会WA在第6组
{
if(t==0.0)
puts("0.000");
else
{
ans=(-b-sqrt(b*b-4.0*a*(c-(r1+r2)*(r1+r2))))/2/a;
printf("%.3f\n",max(ans,0.0));
}
}
else
puts("No collision");
}
return 0;
}



 Problem F A Classy Problem

Accept: 0    Submit: 0

Time Limit: 6000 mSec



 Problem Description

In his memoir “So, Anyway”, comedian John Cleese writes of the class difference between his father (who was “middle-middle-middle-lower-middle class” and his mother (who was “upper-upper-lower-middle class”). These fine distinctions between classes tend to
confuse North American readers, so you are to write a program to sort a group of people by their classes to show their true place in the social class hierarchy. 

For this problem, there are three main classes: upper, middle, and lower. Obviously, the highest is upper and the lowest is lower. But there can be distinctions within a class, so upper-upper is a higher class than middle-upper, which is higher than lower-upper.
However, all of the upper classes (upper-upper, middle-upper, and lower-upper) are higher than any of the middle classes. 

Within a class like middle-upper, there can be further distinctions as well, leading to classes like lower-middle-upper-middle-upper. When comparing classes, once you have reached the lowest level of detail, you should assume that
all further classes are the same as the middle level of the previous level of detail. So upper class and middle-upper class are equivalent, as are middle-middle-lower-middle and lower-middle.



 Input

The first line of input contains a single positive integer T (T ≤ 500) indicating the number of cases to follow. Each case starts with a positive integer n (n ≤ 100) on a line indicating the number of people to consider. Each of the next n lines contains the
name of a person followed by a colon and a space, followed by the class of the person. The name contains up to 30 lowercase characters. The class is a string consisting of a nonempty sequence of up to 10 of the words upper, middle, lower separated by hyphens
(-), followed by a space, followed by the word class. No two people will have the same name in a single case.



 Output

For each test case, print the list of names from highest to lowest class. If two people have the same or equivalent classes, they should be listed in alphabetical order by name. Output a line of 30 equal signs (=) after each case.



 Sample Input

1

5

mom: upper-upper-lower-middle class

dad: middle-middle-middle-lower-middle class

queenelizabeth: upper-upper-upper class

chair: lower-lower class

unclebob: middle-middle-lower-middle class



 Sample Output

queenelizabeth

mom

dad

unclebob

chair

==============================

解题思路:此题做法其实很简单,难就难在题意不好理解,至少我一直没弄明白题目意思,然而学长一眼就看出了题意,佩服佩服

其实对于每个class,我们从后往前与其它class进行比较,按照upper>middle>lower

而对于等效类,例如yyyy-xxxx与xxxx(xxxx与yyyy均为upper,middle,lower的组合),题目中红色字体部分做了说明,虽然我自己没有看懂,但是它的意思是等效类前均补middle,yyyy-xxxx与middle-...-middle-xxxx

待将字符串处理完之后,剩下要做的就是简简单单的排序,O(nlogn)或O(n^2)的排序算法均可

若是还不明白的,可以在下方留言

题目链接→1371 A Classy Problem

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 105;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
struct recipe
{
char name
,ch[2*N],x
;
}s[3*N];
char a[10];
bool cmp(recipe x,recipe y)
{
if(strcmp(x.x,y.x))
return strcmp(x.x,y.x)>0;
return strcmp(x.name,y.name)<0;
}
int main()
{
int t,n,i,j,k,p,x;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%s%s%s",s[i].name,s[i].ch,a);
s[i].name[strlen(s[i].name)-1]='\0';
for(p=j=0;s[i].ch[j]!='\0';j++)
{
if(s[i].ch[j]=='u')
{
s[i].x[p++]='c';
j+=4;
}
else if(s[i].ch[j]=='m')
{
s[i].x[p++]='b';
j+=5;
}
else if(s[i].ch[j]=='l')
{
s[i].x[p++]='a';
j+=4;
}
}
s[i].x[p]='\0';
reverse(s[i].x,s[i].x+p);
while(p<10)
s[i].x[p++]='b';
s[i].x[p]='\0';
//puts(s[i].x);
}
sort(s,s+n,cmp);
for(i=0;i<n;i++)
printf("%s\n",s[i].name);
for(i=0;i<30;i++)
printf("=");
puts("");
}
return 0;
}



 Problem H The Magical 3

Accept: 0    Submit: 0

Time Limit: 3000 mSec



 Problem Description

There’s no doubt about it, three is a magical number. Two’s company,

but three’s a crowd, no one ever talks about 2 blind mice, and there are

three members in an ACM ICPC team.

Even more magically, almost all integers can be represented as a number

that ends in 3 in some numeric base, sometimes in more than one way.

Consider the number 11, which is represented as 13 in base 8 and 23

in base 4. For this problem, you will find the smallest base for a given

number so that the number’s representation in that base ends in 3.





 Input

Each line of the input contains one nonnegative integer n. The value

n = 0 represents the end of the input and should not be processed. All

input integers are less than 2^31. There are no more than 1 000 nonzero values of n.



 Output

For each nonzero value of n in the input, print on a single line the smallest base for which the number has a

representation that ends in 3. If there is no such base, print instead “No such base”.



 Sample Input

11

123

104

2

3

0



 Sample Output

4

4

101

No such base

4

解题思路:此题要我们找到最小的进制满足n转换成该进制表示时最低位为3,如



若不存在,则输出"No
such base"

首先,我们可以知道进制转换是如何实现的

比如要将123转换成4进制



由此可知,要使n转换为x进制后最低位是3,其实就是n mod x = 3,也就是说(n-3)%x==0

要使x尽可能小,所以就是求n-3的最小约数

但是需要注意的是该约数不能小于4,否则x(<4)进制是没法表示3的,这些特判一下就可以了

题目链接→1375 The Magical 3

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 50005;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
int main()
{
int n,i;
bool flag;
while(scanf("%d",&n)&&n)
{
n-=3;flag=false;
if(!n)
{
puts("4");
continue;
}
else if(n<4)
{
puts("No such base");
continue;
}
for(i=4;i<=sqrt(n);i++)
if(n%i==0)
{
flag=true;
break;
}
if(flag)
printf("%d\n",i);
else
{
if(n%3==0&&n/3>=4)
printf("%d\n",n/3);
else if(n%2==0&&n/2>=4)
printf("%d\n",n/2);
else
printf("%d\n",n);
}
}
return 0;
}



 Problem I Matrix Keypad

Accept: 0    Submit: 0

Time Limit: 1000 mSec



 Problem Description

A matrix keypad consists of an r × c grid of buttons. Additionally, there is one wire for each row and one wire for each column. These wires are

exposed through pins so the keypad can be connected to a larger circuit.

When a button at row i and column j is pressed, the wire for row i and the wire for column j will carry an electrical current. If just a single button

is pressed, it can be identified by sequentially checking if a current can be detected at each row wire and at each column wire.

Unfortunately, when multiple buttons are pressed at the same time, it may not be possible to uniquely identify which buttons are pressed. The

only information you can have is this: for each wire, whether there is at least one button along that wire being pressed.

The software you are using to detect which buttons are pressed was poorly implemented. After probing the keypad, it stores the information

in an r × c grid of 0/1 values. The value stored in row i and column j of this grid is 1 if there is at least one button in row i and at least one

(possibly different) button in column j that is pressed. Otherwise, the value that is stored at this position is 0.

Your job is to interpret as much information from such a grid as possible. Determine which buttons are definitely pressed and which buttons are definitely not pressed.





 Input

The first line of input contains a single positive integer T ≤ 200 indicating the number of test cases. The first line of each test case contains two integers r and c where 1 ≤ r ≤ 10 and 1 ≤ c ≤ 10. This indicates that the keypad is an r × c grid of buttons.

The remaining r lines of a test case describe the grid. The ith row contains a string of consecutive 0 and 1 characters. These will not be separated by spaces.



 Output

For each test case, output the following. If there is no combination of button presses on the keypad that would produce this 0/1 grid then simply output a line containing the word impossible

Otherwise, you should output r lines, each containing a string of length c. This should describe a grid where the character at row i and column j is:

• N if no button combination that produces the input grid has the jth button on row i being pressed.

• P if all button combinations that produce the input grid have the jth button on row i being pressed.

• I if some, but not all, button combinations that produce the input grid have the jth button on row i being pressed.

Finally, the last line of each test case should be followed by the string ---------- (10 dashes).



 Sample Input

3

4 3

110

000

110

000

2 3

101

000

2 2

10

01



 Sample Output

IIN

NNN

IIN

NNN

----------

PNP

NNN

----------

impossible

----------

解题思路:此题可以说是一道潜在的水题,之所以这么说是因为比赛的时候仅仅有三个人去做,然而此题却水到不能再水

给你一个0/1矩阵,a(i,j)为1表示第i行至少有一个按钮被按,第j列至少有一个按钮被按,这个按钮可以是同一个(即a(i,j)位置上的那个按钮),也可以是不同的两个,否则a(i,j)为0,现要你确认每个按钮的状态:

N表示这个按钮必定没有被按

P表示这个按钮必定被按

I表示这个按钮可能被按

impossible表示没有按钮组合满足这个0/1矩阵

由于I状态的情况较多,本人是优先判断N,P以及impossible的情况,其余均为I

首先是impossible,不可能的情况只有a(i,j)=0,但第i行和第j列均含有1,这与"The
value stored in row i and column j of this grid is 1 if there is at least one button in row i and at least one (possibly different) button in column j that is pressed."矛盾,故为impossible

其次是N,当a(i,j)=0时,除了impossible的情况以外,其他情况下a(i,j)为0必定能够说明a(i,j)处的按钮没有被按下,否则若a(i,j)处的按钮被按下,那第i行第j列都至少有一个按钮被按下,那a(i,j)也就不可能为0了

再者是P,当a(i,j)=1,若第i行或第j列只有这么一处地方是1,那这个地方的按钮必定是被按下的,否则不满足第i行或第j列至少有一个按钮被按下的条件

最后剩下的皆为I

题目链接→1374 Matrix Keypad

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 15;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
char s

,ans

;
int a
,b
;
int main()
{
int t,r,c,i,j;
bool flag;
scanf("%d",&t);
while(t--)
{
flag=true;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
scanf("%d%d",&r,&c);
for(i=0;i<r;i++)
scanf("%s",s[i]);
for(i=0;i<r;i++)
for(j=0;j<c;j++)
if(s[i][j]-'0')
a[i]++,b[j]++;
for(i=0;i<r&&flag;i++)
{
for(j=0;j<c&&flag;j++)
if(s[i][j]-'0')
{
if(a[i]==1||b[j]==1)
ans[i][j]='P';
else
ans[i][j]='I';
}
else
{
if(a[i]&&b[j])
flag=false;
else
ans[i][j]='N';
}
ans[i][j]='\0';
}
if(flag)
{
for(i=0;i<r;i++)
puts(ans[i]);
}
else
puts("impossible");
for(i=0;i<10;i++)
printf("-");
puts("");
}
return 0;
}


 Problem J I’ve Been Everywhere, Man

Accept: 0    Submit: 0

Time Limit: 1000 mSec



 Problem Description

Alice travels a lot for her work. Each time she travels, she

visits a single city before returning home.

Someone recently asked her “how many different cities have

you visited for work?” Thankfully Alice has kept a log of

her trips. Help Alice figure out the number of cities she has

visited at least once.





 Input

The first line of input contains a single positive integer T ≤ 50 indicating the number of test cases. The first line of each

test case also contains a single positive integer n indicating the number of work trips Alice has taken so far. The following

n lines describe these trips. The ith such line simply contains the name of the city Alice visited on her ith trip.

Alice’s work only sends her to cities with simple names: city names only contain lowercase letters, have at

least one letter, and do not contain spaces.

The number of trips is at most 100 and no city name contains more than 20 characters.



 Output

For each test case, simply output a single line containing a single integer that is the number of distinct cities

that Alice has visited on her work trips.



 Sample Input

2

7

saskatoon

toronto

winnipeg

toronto

vancouver

saskatoon

toronto

3

edmonton

edmonton

edmonton



 Sample Output

4

1

解题思路:此题如果你会用STL里的set的话,还是比较简单的,此题就是问我们出现了多少个不同的字符串,比如第一个样例,出现了"saskatoon"、"toronto"、"winnipeg"、"vancouver"这4个字符串

STL里的set内部其实是一棵红黑树,不知道不要紧,只要知道set里面只会记录下不同的值,最后我只要看看它的size()就知道有多少个不同的字符串

题目链接→1372 I’ve
Been Everywhere, Man

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 50005;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
set<string> s;
int main()
{
int t,n,i;
string ch;
scanf("%d",&t);
while(t--)
{
s.clear();
scanf("%d",&n);
for(i=0;i<n;i++)
{
cin>>ch;
s.insert(ch);
}
printf("%d\n",s.size());
}
return 0;
}


菜鸟成长记
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: