ICPC昆明站训练赛第二场(模拟)

C:Tip to be Palindrome

链接:https://ac.nowcoder.com/acm/contest/12794/C
来源:牛客网

题目描述
One of the cool UCF CS alumni is Dr. Greg, The Palindrome Tipper(回文小费). A palindrome is a string
that reads the same forward and backward, e.g., madam, abba, 3, 44, 525.
One cool thing about Dr. Greg is that he leaves at least 20% tip when he eats out, e.g., if the meal is 30, Dr. Greg leaves 30, Dr. Greg leaves 6 (30*.20) for tip. If the tip (20%) is not a whole dollar amount, he rounds up the tip to make it a whole number. For example, if the meal is 12, a 20% tip would be12,a202.40 (12*0.20) but Dr. Greg would leave $3 for tip.
Another cool thing about Dr. Greg is that he is a palindrome guru. If his total bill (meal plus tip) is not a palindrome, he will increase the total (by adding to the tip) to make the total a palindrome. He will, of course, add the minimum needed to make the total a palindrome.
The Problem:
Given Dr. Greg’s meal cost, your program should determine the tip amount for him (according to his rules) and the total bill.

输入描述:
The first input line contains a positive integer, n, indicating the number of times Dr. Greg ate out. The meal costs are on the following n input lines, one per line. Each input will contain an integer between 5 and 10000 (inclusive).

输出描述:
At the beginning of each test case, output “Input cost: c” where c is the input cost. Then, on the next output line, print the tip amount and the total bill, separated by one space. Leave a blank line after the output for each test case.

示例1
输入
2
12
84
输出
Input cost: 12
10 22

Input cost: 84
17 101

主要思路:
此题的难点主要是非回文时如何构建回文数
因为数据范围较小,可以直接数++,判断是否为回文

#include
using namespace std;
bool judge(int x)
{
    int a[100001],i;
    for(i=0;x;i++)
    {
    	a[i]=x%10;
    	x/=10;
	}
    for(int k=0,j=i-1;k<j;k++,j--)
    {
        if(a[k]!=a[j])
            return 0;
    }
    return 1;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        long long x;
        cin>>x;
        cout<<"Input cost: "<<x<<endl;
        double aa;
        int a;
        aa=0.2*x;
        a=0.2*x;
        if(aa!=a)
            a++;
        a+=x;
        while(!judge(a))
        {
            a++;
        }
        cout<<a-x<<' '<<a<<endl<<endl;
    }
    return 0;
}

D:Soccer Standings

链接:https://ac.nowcoder.com/acm/contest/12794/D
来源:牛客网

题目描述
Soccer fever has gripped the world once again, and millions of people from dozens of countries
will be glued to their TV sets for the World Cup. Being an enterprising sort, you’ve started up your own internet World Cup Soccer Channel for streaming matches online. Recently you came up with the idea of filling up the time between matches by having a couple of ‘experts’ offer critical analysis of games. For this purpose, you have devised a unique ranking system for soccer teams, which you must now implement.
The Problem:
Given a list of teams and a list of match scores, you must compute(计算,估计) several quantities (总量) for each team. These are: the total number of goals scored over all their games(总得分), the total number of goals scored against them (goals allowed, for short), the number of wins, draws and losses, and the number of points scored so far. Points are to be computed as follows: winning a match nets a team 3 points, losing gets them nothing. In the event of a tie(平局), both teams get 1 point.
In addition to this, you must order the teams correctly according to your new system. Teams are ordered according to points, from highest to lowest. In the event of a tie in points, the team that has a higher goal difference comes first. The goal difference is defined as the total number of goals scored by the team minus the total number of goals scored against them.
If there is still a tie (i.e., two or more teams have the same points and the same goal differences), the team with higher total goals scored comes first. If even this is tied, the team whose name comes first in alphabetical order goes first.

输入描述:
The first input line contains a positive integer, n, indicating the number of data sets to be processed. The first line of each data set consists of two positive integers T (T ≤ 30) and G (G ≤
400) – the number of teams in this group and the total number of games played by them. The next line contains T unique names separated by single spaces. Each name is a single uppercase word with no more than 15 characters.
Each of the next G input lines will contain the results of a match. Each line is of the form
. For example, “Greece 2 Nigeria 1” indicates that Greece and Nigeria played a game with score 2-1. All four terms will be separated by single spaces.

输出描述:
At the beginning of output for each data set, output “Group g:” where g is the data set number, starting from 1. Next you should print a single line for each team, ordering teams as mentioned above. For each team, the line you print should be of the form “ ”. These items should be separated by single spaces. Leave a blank line after the output for each data set.

示例1
输入
2
2 1
KASNIA LATVERIA
KASNIA 0 LATVERIA 1
4 6
ENGLAND USA ALGERIA SLOVENIA
ENGLAND 1 USA 1
ALGERIA 0 SLOVENIA 1
SLOVENIA 2 USA 2
ENGLAND 0 ALGERIA 0
SLOVENIA 0 ENGLAND 1
USA 1 ALGERIA 0
输出
Group 1:
LATVERIA 3 1 0 0 1 0
KASNIA 0 0 1 0 0 1

Group 2:
USA 5 1 0 2 4 3
ENGLAND 5 1 0 2 2 1
SLOVENIA 4 1 1 1 3 3
ALGERIA 1 0 2 1 0 2

主要思路:
建立结构题,按题意模拟,易错点①算完一次Group记得清空结构体②排序的规则与顺序

普通结构体:

#include
#include
#include
using namespace std;
struct team
{
    string name;
    int score,won,faliture,ping,zijijinqiushu,duishoujinqiushu;
}a[1000001];
bool cmp(team a,team b)
{
    if(a.score!=b.score)
        return a.score>b.score;
    else if(a.zijijinqiushu-a.duishoujinqiushu!=-b.duishoujinqiushu+b.zijijinqiushu)
        return a.zijijinqiushu-a.duishoujinqiushu>b.zijijinqiushu-b.duishoujinqiushu;
    else if(a.zijijinqiushu!=b.zijijinqiushu)
        return a.zijijinqiushu>b.zijijinqiushu;
    else
        return a.name<b.name;
}
int main()
{
    int t;
    cin>>t;
    int tt=t;
    while(t--)
    {
    	cout<<"Group "<<tt-t<<":"<<endl;
        int n,m;
        cin>>n>>m;
        for(int i=0;i<n;i++)
            cin>>a[i].name;
        while(m--)
        {
            string xx,yy;
            cin>>xx;
            int x,y,xxx,yyy;
            for(int i=0;i<n;i++)
            {
            	if(a[i].name==xx)
            	{
            		x=i;
            		break;
				}
			}
            cin>>xxx;
            cin>>yy;
            for(int i=0;i<n;i++)
            {
            	if(a[i].name==yy)
            	{
            		y=i;
            		break;
				}
			}
            cin>>yyy;
            a[x].zijijinqiushu+=xxx;
            a[y].zijijinqiushu+=yyy;
            a[y].duishoujinqiushu+=xxx;
            a[x].duishoujinqiushu+=yyy;
            if(xxx==yyy)
                a[x].ping++,a[y].ping++,a[x].score++,a[y].score++;
            else if(xxx>yyy)
                a[x].won++,a[y].faliture++,a[x].score+=3;
            else
                a[y].won++,a[x].faliture++,a[y].score+=3;
        }
        sort(a,a+n,cmp);
    for(int i=0;i<n;i++)
    {
        cout<<a[i].name<<' '<<a[i].score<<' '<<a[i].won<<' '<<a[i].faliture<<' '<<a[i].ping<<' '<<a[i].zijijinqiushu<<' '<<a[i].duishoujinqiushu<<endl;
    	a[i].duishoujinqiushu=a[i].faliture=a[i].ping=a[i].score=a[i].won=a[i].zijijinqiushu=0;
    }
	cout<<endl;
    }
    return 0;
}

哈希表:

E:NIH Budget

链接:https://ac.nowcoder.com/acm/contest/12794/E
来源:牛客网

题目描述
Recently, a job for an algorithms specialist opened up at NIH. You never thought you’d be using your expertise in algorithms(算法) to save lives, but now, here is your chance! While the doctors are very good in carrying out medical research and coming up with better cures for diseases, they are not so good with numbers. This is where you come in.

You have been tasked to allocate(分配) money for all disease research at NIH. The interesting thing about disease research is that the number of lives saved doesn’t linearly increase with the amount of money spent, in most cases. Instead, there are “break-points”. For example, it might be the case that for disease A, we have the following break-points:

Research Funding

Lives Saved

10 million

5

50 million

100

100 million

1000

250 million

1100

If you spend more money than one breakpoint and less than another, the number of lives saved is equal to the amount saved for the previous breakpoint. (In the above example, if you spent 150 million, you’d still only save 1000 lives, and if you spent any amount more (这里很重要)than150million,you’dstillonlysave1000lives,andifyouspentanyamountmorethan250 million, you’d still save 1100 lives.)

The doctors have figured out charts just like this one for all the diseases for which they do research. Given these charts, your job will be to maximize the number of lives saved spending no more than a particular budget.

The Problem:

Given several charts with information about how much has to be spent to save a certain number of lives for several diseases and a maximum amount of money you can spend, determine the maximum number of lives that can be saved.

输入描述:
The first input line contains a positive integer, n (n ≤ 100), indicating the number of budgets to consider. The first line of each budget contains two positive integers, d (d ≤ 10), representing the number of diseases for which there is data and B (B ≤ 100000), the total budget(总预算), in millions of dollars. The following d lines contain information about each of the d diseases. Each of these lines will contain exactly four ordered pairs(四对) of positive integers separated by spaces. Each pair will represent a dollar level (in millions) followed by the number of lives saved for that dollar (花费,救人数)

level of funding. Each of the pairs will be separated by spaces as well. Each of these values will be less than or equal to 100,000. Assume that the dollar levels on an input line are distinct and in increasing order, and that the number of lives saved on an input line are also distinct and in increasing order.

输出描述:
For each test case, just output a line with the following format:
Budget #k: Maximum of x lives saved.
where k is the number of the budget, starting at 1, and x is the maximum number of lives saved in that budget.
Leave a blank line after the output for each test case.

示例1
输入
3
2 2000
10 5 50 100 100 1000 250 1100
100 1 200 2 300 3 1900 1000
3 100
10 100 40 200 70 300 100 500
5 1 25 2 35 3 50 4
200 10000 300 20000 400 30000 500 40000
1 10
100 2 200 3 300 5 400 6
输出
Budget #1: Maximum of 2000 lives saved.

Budget #2: Maximum of 500 lives saved.

Budget #3: Maximum of 0 lives saved.

主要思路:
看清题目,一类只能选一个
①搜索
②01背包

搜索:

#include
#include
using namespace std;
int ans,n,v;        
int s[1001][1001],w[1001][1001];
void dfs(int sum,int now,int leave)//一层加一个数
{
    if(leave<0)//超过预算
        return;
    if(now>=n)
    {
        ans=max(ans,sum);
        return;
    }
    for(int i=0;i<5;i++)//每层从四个中随机选
        dfs(sum+w[now][i],now+1,leave-s[now][i]);
}
int main()
{
    int nn;
    cin>>nn;
    int nnn=nn;
    while(nn--)
    {
        ans=0;

        cin>>n>>v;
        for(int i=0;i<n;i++)
            for(int j=1;j<5;j++)
                cin>>s[i][j]>>w[i][j];
        dfs(0,0,v);
        cout<<"Budget #"<<nnn-nn<<": Maximum of "<<ans<<" lives saved."<<endl<<endl;
    }
    return 0;
}

01背包:

#include
#include
using namespace std;
int main()
{
    int t,tt;
    cin>>t;
    tt=t;
    while(t--)
    {
        int ans=0;
        int n,v,f[100001]={0};
        cin>>n>>v;
        int s[101][101],w[101][101];
        for(int i=0;i<n;i++)
            for(int j=0;j<4;j++)
                cin>>s[i][j]>>w[i][j];
        for(int i=0;i<n;i++)
            for(int j=v;j>0;j--)
                for(int k=0;k<4;k++)
                    if(j>=s[i][k])
                    {
                        f[j]=max(f[j],f[j-s[i][k]]+w[i][k]);
                   }
       cout<<"Budget #"<<tt-t<<": Maximum of "<<f[v]<<" lives saved."<<endl<<endl;
    }
    return 0;
}

F:Interstellar Love

链接:https://ac.nowcoder.com/acm/contest/12794/F
来源:牛客网

题目描述
After two years of sharing a bedroom with you in a college dorm, Jeff finally has his own room. Excited about inviting girls over to his room, he ponders over what decorations the fairer sex will enjoy.1 He decides upon setting up a “fake” planetarium(星座) with a black ceiling and glow in the dark stars that form constellations. Unfortunately, in his haste(匆忙), he has made several “errors” in setting up his constellations. See, everyone knows that constellations don’t have cycles in them. Instead, whenever we visually connect the stars together with lines, a tree is always formed. (A cycle is formed when you can start at a star and, using connections, go to one or more other stars and then end up at the original star.)

Since you were Jeff’s roommate for two years, you figure you’ll help him fix his constellations. Your job will be twofold: to count the number of constellations Jeff has, and to report how many of them have cycles(自环) and need to be fixed. A constellation consists of multiple stars that are all connected to one another(连接的才算一个) (directly or indirectly). A constellation that needs fixing is simply one that has a cycle.

The Problem:

Given several configurations of stars and connections between stars, determine how many constellations are defined in each configuration and how many need fixing.

输入描述:
The first input line contains a positive integer, n (n ≤ 100), indicating the number of night skies to consider. The first line of each night sky contains two positive integers, s (s ≤ 1000), representing the number of stars for this night sky, and c (c ≤ 10000), representing the total number of connections between pairs of stars for this night sky. Each of the following c input lines contains two distinct positive integers representing a single connection between two stars. The stars in each test case will be numbered 1 through s, inclusive. A connection is considered bidirectional, thus, if a is connected to b, b is connected to a. Assume that all connections in a data set are distinct, i.e., no duplicates. Also assume that there will never be a connection from a star to itself.

1 This is based on a true story. The person who is the inspiration for this story did, in fact, major in Planetary Science and make his room’s ceiling a relatively accurate depiction of the night sky, as seen in Boston circa 1995.

输出描述:
For each test case, just output a line with the following format:
Night sky #k: X constellations, of which Y need to be fixed.
where k is the number of the night sky, starting at 1, X is the total number of constellations described in that night sky, and Y is how many of those constellations contain a cycle.
Leave a blank line after the output for each test case.

示例1
输入
3
5 4
1 2
1 3
2 3
4 5
8 5
1 2
3 4
6 7
6 8
8 7
3 2
1 2
1 3
输出
Night sky #1: 2 constellations, of which 1 need to be fixed.

Night sky #2: 3 constellations, of which 1 need to be fixed.

Night sky #3: 1 constellations, of which 0 need to be fixed.
说明
Note:In the second example, star number 5 is not connected to any other stars. This staron its own is NOT counted as a constellation, leaving only {1,2}, {3,4}and {6,7,8} as constellations, of which only the last one needs tobe fixed.

主要思路:
并查集问题
flag1标记是否重复加入并查集,如果有则后边利用循环将f[i]标记
flag2标记是否有联通

错误思路:开始用搜索做的先建立邻接表,1->n循环,以没标记的点为头,搜索标记,但是存在如下问题——例如,1->2->3->4->2可是2已经被标记,且1没有被标记,所以不判断为自环,而2已经被标记了,不能重复搜索了。

#include
#include
using namespace std;
int f[100001],flag1[100001],flag2[1000001];
int find(int k)
{
	if(f[k]==k)
		return k;
	else
		return f[k]=find(f[k]);
}
void unio(int x,int y)
{
	if(find(x)==find(y))//判断是否自环 
		flag1[find(x)]=1;
	else//判断是否联通 
	{
		f[find(x)]=find(y);
		flag2[find(y)]=1;
	}
}
int main()
{
	int t,tt;
	cin>>t;
	tt=t;
	while(t--)
	{	
        memset(f,0,sizeof(f));
        memset(flag1,0,sizeof(flag1));
        memset(flag2,0,sizeof(flag2));
		int n,m,ans1=0,ans2=0;
		cin>>n>>m;
		for(int i=0;i<=n;i++)
			f[i]=i;
		while(m--)
		{
			int x,y;
			cin>>x>>y;
			unio(x,y);
		}
		for(int i=1;i<=n;i++)
		{
			if(flag1[i])//保证存在自环的一个集合里所有的元素全部被flag1标记
				flag1[find(i)]=1;
		}
		for(int i=1;i<=n;i++)
		{
			if(f[i]==i&&flag2[find(i)])
			{
				ans1++;
				if(flag1[i])
					ans2++;
			}
		}
		cout<<"Night sky #"<<tt-t<<": "<<ans1<<" constellations, of which "<<ans2<<" need to be fixed."<<endl<<endl;
	}
    return 0;
}

G:Plate Spinning

链接:https://ac.nowcoder.com/acm/contest/12794/G
来源:牛客网

题目描述
Plate spinning is a circus (马戏,杂技) act where a person spins various objects(usually plates and bowls) on poles without them falling off. It involves spinning an object and then returning back to the object in order to add additional speed to prevent it from falling off the pole.
In this problem you will simulate plate spinning where the plates are placed in a circular arrangement (much like the picture to the right). You must determine whether Chester the Clown will be able to maintain the plates spinning or whether one or more plates will end up falling off poles.

The Problem:
Given the number of poles/plates in a circular arrangement and the speed up to which Chester the Clown spins the plates (in degrees per second), determine if he can maintain the act or if plates will fall. For this problem, we will assume that plates degrade (slow down) at a constant rate of 5-degrees-per-second per second and that Chester can move from one pole to any other pole in 0.5 seconds. In addition, assume that Chester can spin up a plate with zero time cost.
A plate falls off when its rate is zero. However, if Chester arrives at a plate exactly at the same time the rate reaches zero, Chester will spin the plate and prevents it from falling, i.e., the rate must reach zero before Chester arrives for the plate to fall.

输入描述:
The first line of the input will be a single positive integer, a, representing the number of acts to evaluate. Each of the following a lines will represent a single act and will contain two positive integers, n and p, separated by a single space, where n represents the number of poles (1 ≤ n ≤ 15) and p represents the speed up to which Chester spins a plate (0 < p ≤ 100) in degrees per second. At the very beginning of each act, all plates are initially spinning at this speed, and he is currently at a plate in the circle (he can choose which plate to start at in order to maximize his chance of success).

输出描述:
For each circus act, output a header “Circus Act i:” on a line by itself where i is the number of the act (starting with 1). Then, on the next line, output “Chester can do it!” if Chester can maintain the act, or output “Chester will fail!” if one or more plates will fall. Leave a blank line after the output for each test case.

示例1
输入
3
2 10
5 7
2 12
输出
Circus Act 1:
Chester can do it!

Circus Act 2:
Chester will fail!

Circus Act 3:
Chester can do it!

主要思路:
读懂题即可,很简单

#include
using namespace std;
int main()
{
    int t,tt;
    cin>>t;
    tt=t;
    while(t--)
    {
        cout<<"Circus Act "<<tt-t<<':'<<endl;
        double x,y;
        cin>>x>>y;
        if(x<=y*2.0/5||x==1)
            cout<<"Chester can do it!"<<endl<<endl;
        else
            cout<<"Chester will fail!"<<endl<<endl;
    }
    return 0;
}

H:The Eternal Quest for Caffeine

链接:https://ac.nowcoder.com/acm/contest/12794/H
来源:牛客网

题目描述
Like most engineering students, Jason relies on caffeine, soda in particular, to get him through long nights in the lab. He’s not too picky about the brand; as long as it’s fizzy, loaded with caffeine, and not the “diet” version, he’s happy. When the new Harris Engineering Center opened on the UCF Campus, he was pleased to see a soda machine on every floor. Not just any soda machine, either. These machines are the fancy kind that display all of the soda stock arranged in rows stacked on top of each other (like most snack machines). When a soda is purchased, a conveyor belt rises to the correct row, where the soda is surgically picked up by a robotic clasp that can travel left and right on the conveyor. The conveyor then descends to the vending slot, where the clasp gently deposits the soda. Finally, the slot unlocks and tilts forward, allowing the buyer to retrieve his or her soda. Engineering perfection! And as a bonus, the soda isn’t subjected to all the usual mechanical clatter that causes it to fizz over when it’s opened.

Unfortunately, these elaborate machines seem to have a propensity for component failure. On one soda mission from his lab, Jason discovered that the vending slot was broken on the machine on his floor, which prevented it from working altogether. He went to the next floor down and saw that that machine’s vending slot was fine, but the conveyor was broken. He went down to the ground floor and saw that that machine was in perfect order, but only had caffeine free diet soda! At this point, Jason devised a plan. It’s a simple matter for him to open up the working machine and harvest the parts he needs for the machine upstairs, then to hike back upstairs and repair the machine that houses the soda he needs. Sure, hecouldjust take the soda he wants while the machine is open, but what fun would that be?

The one issue with this plan is that while Jason does enjoy the engineering challenge, he hates the walking between various broken machines each time he goes to get a coke, so he’s asked you, a computer science student and fellow resident of the Harris Engineering Center to help. He can devise a way to monitor each machine in the building and ascertain what parts are working. He needs you to write a program that will allow him to get all the parts he needs from the various machines in the building, traveling up and down as few flights of stairs as possible (he doesn’t trust the elevators because he’s never been allowed to see how they work). Assume he can carry an unlimited number of parts. He also wants this algorithm to work for various kinds of coke machines and various buildings, in case the vendors decide to change out their machines one day, or the administration decides to relocate the EECS department again (you still can assume that there will always be exactly one coke machine on each floor).

The Problem:

Given the number of floors in the building, the number of parts required for a working machine, a description of the working parts in each machine in the building, and whether or not each machine has the desired kind of soda(是否有他喜欢的这种苏打水), determine the smallest number of floor changes required(至少需要改变多少次楼层) to assemble(集合) a working machine that is already stocked with the desired soda. Jason will always start from his lab and return there after getting his soda.

输入描述:
There will be multiple sodamachine arrangements to process. Inputwill begin with three integers,N,F, andP(1 ≤N,F,P≤ 10), each separated by a singlespace with no leading or trailingspaces.Ndescribes the number of floors in the building,Findicates which floor Jason’s lab is on, andPindicates the number of different partsin each of the building’s soda machines.

On the nextNlines will be a set of integersfollowed by a single letter. Eachline describes the soda machine onone floor (starting with the ground floor, and proceeding upward in order). The characterson a line are separated by a single space, with no leading or trailing spaces.The first integers on each line will beS(0 ≤S≤P), indicating the number of workingparts in the machine.Sintegerswill follow, each indicating a working part in the machine (each of these integers will be unique and will bebetween 1 andP). Finally, there willbe a single character “Y” or “N”, where “Y” indicates that themachine has a kind of soda that Jason likes, and “N” indicates that it does not.

End of input will beindicated by a value of 0forN,F, andP. This case should not be processed.

输出描述:
For each soda machinearrangement, print the case number (starting with 1) and a single integer indicating the minimum number of timesJason will have to travel up or down a staircase to collect the parts he needs to repair a soda machine, get a sodathat he wants, and return to his lab. Ifthere is no way for Jason to get a soda, print “Impossible” instead of the integer. Leavea blank line after the outputfor each test case.

示例1
输入
4 2 5
5 1 2 3 4 5 N
4 1 2 3 5 Y
4 1 2 4 5 Y
5 1 2 3 4 5 Y
4 2 6
1 1 Y
2 2 3 Y
3 1 4 5 Y
0 Y
0 0 0
输出
Test case #1: 2

Test case #2: Impossible

主要思路:
模拟,先利用二维数组存储零件,char存储YorN,然后利用a*(上楼加下楼)
循环寻找最小值

#include
#include
#include
using namespace std;
int n,now,x;
int main()
{
    int t=0;
    while(cin>>n>>now>>x&&n&&now&&x)
    {
        t++;
        int k,a[101][101]={0};
        bool book[10001]={0};
        char s[10001];
        int ans=999999999;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i][0];
            for(int j=1;j<=a[i][0];j++)
                cin>>a[i][j];
            cin>>s[i];
        }
        for(int i=1;i<=now;i++)//是否上楼,以及上多少层
        {
            for(int j=now;j<=n;j++)
            {
                memset(book,0,sizeof(book));
                int flag=0;//判断是否有机器有他要的苏打水
                int num=0;//记录不同的零件数
                for(int k=i;k<=j;k++)
                {
                    if(s[k]=='Y') flag=1;
                    for(int l=1;l<=a[k][0];l++)
                    {
                        if(!book[a[k][l]])
                        {
                            num++;
                            book[a[k][l]]=1;
                        }
                    }
                }
                if(num>=x&&flag)
                    ans=min(ans,2*(j-i));
            }
        }
        cout<<"Test case #"<<t<<": ";
        if(ans==999999999)
            cout<<"Impossible"<<endl<<endl;
        else
            cout<<ans<<endl<<endl;
    }
    return 0;
}

I:Pegasus Circle Shortcut

链接:https://ac.nowcoder.com/acm/contest/12794/I
来源:牛客网

题目描述
For the UCF High School Programming Tournament, the judges were located in the Engineering building, and most of the teams were in the Classroom building, which is on the other side of Pegasus Circle.

Chris was walking to the Classroom building for the first time, and was joined by Jeremy, who had made the hike a couple of times already.

“Jeremy, is it faster to stay on the circle, or to cut through the middle using the boardwalks that go to the Student Union?” asked Chris.

“I don’t know.” Jeremy answered. “I think it’s about the same, but it might be slightly faster to use the walkways.”

“Well, if it’s about the same, let’s stick to the circle. I don’t want to be attacked by squirrels.”

The Problem:

Given two points on a circle, and two paths to get from one to the other—one following the perimeter(周围) of the circle, and the other by a sequence of connected straight line segments (分割,段)through the interior(内部) of the circle—determine the shorter of the two paths.

输入描述:
The input will contain multiple test cases, each consisting of two lines. The first line of each testcase contains six floating-point numbers:xc,yc,xs,ys,xf, andyf, where (xc,yc) is the center point of the circle, (xs,ys) is the start point for both paths (e.g., the Engineering building), and (xf,yf) is the finish point for both paths (e.g., the Classroom building).The circle will always have a radius greater than 1, and the start and finish points are both guaranteed to be at distinct pointson its perimeter, with an accuracy of at least 3 placesafter the decimal.The path along the perimeter is always in the directioncounter-clockwise around the circle.

The second line of each test case will start with an integer,n(1≤n≤ 10), followed by n pairs of floating-point numbers,x1,y1,x2,y2, …xn, and yn, where each pair (xi,yi) is a point inside the circle. The interior path traveled will be from point (xs,ys) to point (x1,y1), then from (x1,y1) to (x2,y2), then from (x2,y2) to (x3,y3), …, then from (xn,yn) to (xf,yf).

The last test case will be followed by a line containing six zeros. All numbers on an input line will beseparated from each other by one space, with no extra spaces at the beginning or end of lines. Assumethat all the input floating point numbers will be less than 1000.0 and greater than

-1000.0, with at most 6 places after the decimal.

输出描述:
For each test case in the input, output a line in either the format

Case #n:Stick to the Circle.

if the perimeter path is shorter,or

Case #n:Watch out for squirrels!

if the interior pathis shorter, where n is the num berof the input test case, starting at 1.

Assume that the two paths will not be equal, i.e., it is guaranteed that the two distances will not be equal. In particular, assume that the two paths will differ in length by 0.001 or more.

Leave a blank line after the output for each test case.

示例1
输入
5.0 5.0 10.0 5.0 5.0 10.0
6 8.5 4.7 6.9 5.0 3.6 6.5 4.2 7.1 4.2 8.3 4.7 8.8
2.0 8.0 0.5 16.87412 7.5 0.8761
2 3.25 9.25 7.0 7.0
0 0 0 0 0 0
输出
Case #1: Stick to the Circle.

Case #2: Watch out for squirrels!

主要思路:
模拟
利用求弧长的公式

#include
#include
using namespace std;
int main()
{
    int t=0;
    double x0,x1,x2,y0,y1,y2;
    while(cin>>x0)
    {
        cin>>y0>>x1>>y1>>x2>>y2;
        if(x0==0&&!x1&&!x2&&!y1&&!y0&&!y2)
            break;
        t++;
        double r=sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
        double L1=r * acos( ((x1-x0)*(x2-x0)+(y1-y0)*(y2-y0)) / (r*r) );//求弧长公式
        double a=x1,b=y1,c,d,L2=0;
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)//这个循环处理很巧妙
        {
            cin>>c>>d;
            L2+=sqrt((a-c)*(a-c)+(b-d)*(b-d));
            a=c,b=d;
        }
        L2+=sqrt((a-x2)*(a-x2)+(b-y2)*(b-y2));
        cout<<"Case #"<<t<<": ";
        if(L1 < L2)
            cout<<"Stick to the Circle."<<"\n\n";
        else
            cout<<"Watch out for squirrels!"<<"\n\n"; 
    }
    return 0;
}

J:Lowest Common Ancestor

链接:https://ac.nowcoder.com/acm/contest/12794/J
来源:牛客网

题目描述
Perfect binary trees are one of the coolest structures that computer scientists study. They have a lot of properties that make them very nice to work with. One of the nicest properties is that they can just be described by a single integerngiving the depth of the tree. For instance, the perfect binary tree forn= 3 looks like:

In general, a perfect binary tree with depthnwill have exactly 2n+1 – 1 nodes, and can be numbered by following the pattern seen above (there are of course other ways to number the nodes of the tree, but this is the scheme we will use in this problem).

A common question that arises when dealing with trees is the query of the lowest common ancestor (commonly called LCA) of two nodes in the tree. Formally, the LCA ofxandyis the nodezof greatest depth in the tree such thatzis an ancestor ofxandy. Nodeais an ancestor of nodecifcexists in the sub-tree rooted at nodea. Notice that 1 is trivially a common ancestor of any two nodes in the tree, but is not always thelowestcommon ancestor. For instance, the common ancestors of nodes 7 and 12 are 1 and 3, and 3 is the LCA since it is the node of greatest depth. The LCA of 2 and 13 is node 1, and the LCA of 5 and 11 is node 5. The definition of LCA guarantees that the LCA of any two nodes will always be unique.

The Problem:

Given two nodes in the tree using the numbering scheme shown above, determine the LCA of the two nodes.

输入描述:
Input will begin with apositive integer,T≤ 2∙106,indicating the number of test cases. Thiswill be followed byTtest cases, each on a separate inputline. Each test case will contain twospace separated integers,XandY, represented in hexadecimal.XandYwill each contain at most 1000characters from the set {0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f}, where a-frepresent 10-15, respectively. You are todetermine the LCA ofXandY.

Note: The hexadecimal (base 16) numberdndn-1···d1d0 is converted to a decimal number (base 10) by the followingformula:d0·160 +d1·161 + ··· +dn-1·16n-1 +dn·16n.

输出描述:
For each case, output a singleline:Case#x:ywherexis the case number beginning with 1, andyis the LCA in hexadecimal with no leading 0’s. Leave a blankline after the output for each testcase.

示例1
输入
7
7 c
2 d
b 5
10 11
a020fac a030ccf
12afcdb 12afcdc
100000000 fffffffff
输出
Case #1: 3

Case #2: 1

Case #3: 5

Case #4: 8

Case #5: 501

Case #6: 255f9b

Case #7: 1

主要思路:
二叉树的两个字节的分别是2x,2x+1
所以将16进制转换为2进制,找最大的前缀和

#include
#include
using namespace std;
int main()
{
    int t,tt;
    cin>>t;
    tt=t;
    while(t--)
    {
        string a,b;
        cin>>a;
        getchar();
        cin>>b;
        int aa[10001],bb[100001];
        int l1=a.size(),l2=b.size();
        for(int i=0;i<l1;i++)
        {
            int x;
            if(a[i]>='0'&&a[i]<='9')//字符串转换为数字
                x=a[i]-'0';
            else if(a[i]>='a'&&a[i]<='f') 
                x=a[i]+10-'a';
            for(int j=3;j>=0;j--)//转换为2进制
            {
                aa[i*4+j]=x%2;
                x>>=1;
            }
        }
        for(int i=0;i<l2;i++)
        {
            int x;
            if(b[i]>='0'&&b[i]<='9')
                x=b[i]-'0';
            else
                x=b[i]+10-'a';
            for(int j=3;j>=0;j--)
            {
                bb[i*4+j]=x%2;
                x>>=1;
            }
        }
        l1*=4,l2*=4;//长度变为原来的四倍
        int p,q;
        for( p=0;;p++) if(aa[p]) break;
        for(q=0;;q++) if(bb[q]) break;
        int l=p-1;//记得减一,否则会和下边判断重复多加一个1
        for(;p<l1&&q<l2;p++,q++)//从第一个有数的地方判重
        {
            if(aa[p]==bb[q]) l++;
            else break;
        }
        char ans[100001];
        int e=-1,x=-1,k=0;//x=-1
        for(int i=l;i>=0;i--)
        {
            e++;
            e%=4;
            if(e==0)
            {
                if(x>=0&&x<=9) ans[k++]=char(x+'0');
                else if(x>9)ans[k++]=char('a'+x-10);//排除x=-1,且下边的x=0可消去-1
                x=0;
            }
            x+=aa[i]*(1<<e);//0,2,4,8
        }
        if(x!=0)
        {
               if(x>=0&&x<=9) ans[k++]=char(x+'0');
                else ans[k++]=char('a'+x-10);
        }
        cout<<"Case #"<<tt-t<<": ";
        for(int i=k-1;i>=0;i--)//输入时是111<-依次输入,所以后输入的最大,先输出
        	cout<<ans[i];
		cout<<endl<<endl;
    }
    return 0;
}

你可能感兴趣的:(ICPC昆明站训练赛第二场(模拟))