第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明),签到题4题

Posted 小哈里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明),签到题4题相关的知识,希望对你有一定的参考价值。

文章目录

补题链接:https://ac.nowcoder.com/acm/contest/12548

H. Hard Calculation

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

题目描述
Hooray! It is the first time that Kunming holds an ICPC regional contest. Suppose that everything goes on well and the Kunming Regional Contest is held each year. In which year will the xx-th Kunming Regional Contest be held?
输入描述:
The first and only line of input contains a single integer x(1\\leq x\\leq 100)x(1≤x≤100).
输出描述:
Output a single integer, denoting the year when the xx-th Kunming Regional Contest will be held.
示例1
输入
复制
1
输出
复制
2021
示例2
输入
复制
100
输出
复制
2120
备注:
Note that it is the year 2021 right now.

题意:

  • 给出一个x,求2020后的第x个年是第几年

思路:

  • 直接输出2020+x
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
int main()
	int x;  cin>>x;
	cout<<2020+x<<"\\n";
	return 0;



I. Mr. Main and Windmills

题目描述
Mr. Main took a train from city to city and passed a plain full of windmills. The train ran in a straight line. A windmill is a machine used for wind power generation. Its fan blades rotate when the wind blows. From his perspective, colorful windmills lined up on the horizon from left to right.

As the train was running, the order of windmills from his perspective was constantly changing: a windmill was originally on the left/right of another, and then changed to its right/left;

Given the coordinates of the windmills, please find the coordinate of him when he just observed the -th windmill exchanged order with other windmills for the -th times. It is guaranteed that any three of the points given, the cities and the windmills, were not collinear, and that all of the windmills were on the same side of the line that the train ran along.

As shown in the picture, in Mr. Mian’s perspective, B was initially to the left of A, and later to the right of A.
输入描述:
The first line of input contains two integers and , where is number of windmills, and is number of queries.

The second line contains four integers x_s, y_s, x_t and y_t (), which are the coordinates of the starting city s and destination city t.

The next lines describe the windmills, the -th of which contains two integers x_i,
y_i (), which are the coordinates of the -th windmill.

The next lines describe the queries, the -th of which contains two integers, h_i and k_i (), denoting a query for the coordinates when observing the k_i-th pass of the h_i-th windmill.
输出描述:
Output m lines, each containing two real numbers x_i, y_i, representing the coordinates when the h_i-th windmill is observed to exchange order with other windmills for k times; if it does not exist, output -1. Your answer is considered correct if its absolute or relative error with the standard answer is less than .
示例1
输入
复制
4 2
0 0 5 0
1 3
2 4
4 1
4 5
1 2
3 2
输出
复制
-1
4.6666666667 0.0000000000

题意:

  • 给出n个点的坐标,以及额外的起点和终点。从起点沿直线走到终点,从过程中的每个点看这n个点都会看到相对位置的变化。
  • 给出m个询问,对于第h个点,从起点走到终点的过程中,有多少个点相对于他的左右位置发生了变化,求第k个点的坐标,如果小于k就-1.

思路:

  • 对于询问点hi,枚举其他所有点j,求他们连线与起点终点的交点,如果交点在起点终点上,那么就会发生变化,反之不会。
#include <bits/stdc++.h>
using namespace std;

//精度
const double eps=1e-9;
int sign(double k)if(k>eps)return 1;else if(k<-eps)return -1; return 0;
int cmp(double k1,double k2)return sign(k1-k2);

//向量
struct point
	double x, y;
	point operator + (const point& k1)constreturn pointx+k1.x,y+k1.y;
	point operator - (const point& k1)constreturn pointx-k1.x,y-k1.y;
	point operator * (double k1)constreturn pointx*k1,y*k1;
	point operator / (double k1)constreturn pointx/k1,y/k1;
;
double cross(point k1,point k2)return k1.x*k2.y-k1.y*k2.x;

//题目
int check(point k1, point k2, point k3, point k4)
	return cmp(cross(k3-k1,k4-k1),cross(k3-k2,k4-k2))!=0;

int inmid(double k1,double k2,double k3)return sign(k1-k3)*sign(k2-k3)<=0;
int inmid(point k1,point k2,point k3)return inmid(k1.x,k2.x,k3.x)&&inmid(k1.y,k2.y,k3.y);
point getp(point k1,point k2,point k3,point k4)
  double w1=cross(k1-k3,k4-k3),w2=cross(k4-k3,k2-k3); return (k1*w2+k2*w1)/(w1+w2);


int main()
	int n, m;  cin>>n>>m;
	point s, t;  cin>>s.x>>s.y>>t.x>>t.y;
	vector<point>p(n+1);
	for(int i = 1; i <= n; i++)
		cin>>p[i].x>>p[i].y;
	
	for(int i = 1; i <= m; i++)
		int h, k;  cin>>h>>k;
		
		vector<point>vc;
		for(int j = 1; j <= n; j++)
			if(j==h)continue;
			if(check(p[h],p[j],s,t))//是否相交
				point q = getp(p[h], p[j], s, t);
				if(inmid(s,t,q))//是否在线段上
					vc.push_back(q);
				
			
		
		
		if(s.x==t.x)//竖直线
			sort(vc.begin(), vc.end(), [&](point a, point b)return a.y<b.y;);
			if(s.y>t.y)reverse(vc.begin(), vc.end());
		else
			sort(vc.begin(), vc.end(), [&](point a, point b)return a.x<b.x;);
			if(s.x>t.x)reverse(vc.begin(), vc.end());
		
		
		if(vc.size()>=k)
			printf("%.10lf %.10lf\\n",vc[k-1].x,vc[k-1].y);
		else 
			cout<<"-1\\n";
	
	return 0;


L. Simone and graph coloring

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

题目描述
Simone, a student of Graph Coloring University, is interested in permutation. Now she is given a permutation of length nn, and she finds that if she connects each inverse pair, she will get a graph. Formally, for the given permutation, if i<jia_ja
i

a
j

, then there will be an undirected edge between node ii and node jj in the graph.

Then she wants to color this graph. Please achieve poor Simone’s dream. To simplify the problem, you just need to find a way of coloring the vertices of the graph such that no two adjacent vertices are of the same color and minimize the number of colors used.

输入描述:
There are multiple test cases. The first line of the input contains an integer T(1\\leq T\\leq 10^6)T(1≤T≤10
6
), indicating the number of test cases.

For each test case, the first line contains an integer n(1 \\leq n \\leq 10^6)n(1≤n≤10
6
), indicating the length of the permutation.

The second line contains nn integers a_1,a_2,…,a_na
1

,a
2

,…,a
n

, indicating the permutation.

It is guaranteed that the sum of nn over all test cases does not exceed 10^610
6
.
输出描述:
For each test case, the first line contains an integer cc, the chromatic number(the minimal number of colors been used when coloring) of the graph.

The second line contains nn integers c_1,c_2,…,c_nc
1

,c
2

,…,c
n

, the color of each node.

Notice that c_ic
i

should satisfy the limit that 1 \\leq c_i \\leq c1≤c
i

≤c.

If there are several answers, it is acceptable to print any of them.
示例1
输入
复制
2
4
1 3 4 2
2
1 2
输出
复制
2
1 1 1 2
1
1 1

题意:

  • 给出一个长度为n的排列,对于i<j且ai>aj的点连一条无向边。
  • 求给该图染色需要的最少颜色数,构造一种染色方案,输出每个点的颜色。

思路:

  • 就强行暴力,从后往前枚举,每次找到在当前数右边中比当前数小的数中颜色最大的数,颜色加一。
  • 因为查找的复杂度不够所以用rmq维护。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;

int n, a[maxn], c[maxn];

int f[maxn];
void add(int i, int v) for(;i<=n;i+=i&(-i))f[i]=max(f[i],v);
int query(int i)int ans=0;for(;i>0;i-=i&(-i))ans=max(ans,f[i]);return ans;

int main()
	//ios::sync_with_stdio(false);//TLE
	int T;  scanf("%d",&T);
	while(T--)
		//memset(f,0,sizeof(f));
		for(int i = 1; i <= n; i++)f[i] = 0;
		scanf("%d",&n);
		for(int i = 1; i <= n; i++)scanf("%d",&a[i]);
		
		int ans = 0;
		for(int i = n; i >= 1; i--)
			c[i] = query(a[i])+1;
			add(a[i],c[i]);
			ans = max(ans, c[i]);
		
		//cout<<ans<<"\\n";
		printf("%d\\n",ans);
		for(int i = 1; i <= n; i++)
			printf("%d ",c[i]);
		printf("\\n");
	
	return 0;


J.Parallel Sort

As a master of parallel computing, schwer is recently considering about the method to achieve quick sorting on parallel computers. He needs your help!

Given a permutation (p_1,\\cdots,p_n)(p
1

,⋯,p
n

), you need to sort the permutation with minimum number of rounds. In a single round, one can take many pairs of integers (x_1,y_1),\\cdots,(x_k,y_k)(x
1

,y
1

),⋯,(x
k

,y
k

) as long as the values of x_1,y_1,\\cdots,x_k,y_kx
1

,y
1

,⋯,x
k

,y
k

are pairwise distinct. Then with the help of kk CPUs, for each i\\in [1,k]i∈[1,k], the value of p_x_ip
x
i


and p_y_ip
y
i


will be switched immediately. Note that a permutation (p_1,\\cdots,p_n)(p
1

,⋯,p
n

) is sorted if for every integer i\\in [1,n]i∈[1,n], p_i=ip
i

=i holds.

Take some examples. Assume that n=4n=4. For p=(1,2,3,4)p=(1,2,3,4), the minimum number of round is 00 as it is already sorted. For p=(4,3,2,1)p=(4,3,2,1), the answer is 11, as you can swap the indices (1,4)(1,4) and (2,3)(2,3) simultaneously.

题意:

  • 给出一个排列,每次可以交换任意对数(a[i],a[j])。
  • 求最小交换次数让其变成升序,并输出每次交换的数对

思路:

  • 对于每个环:如果环中只有两个数,那么一次交换即可.
    如果环中超过两个数,那么两次交换即可比如(2,3,n,1),只需要两步(1,n,n-1,2),(1,2,3,n)就可以有序,如4567123,3217654,1234567。
  • 因为无序序列是由若干个独立环交换后形成的,所以答案最多两次交换,构造环的时候每次去查找即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int a[maxn], p[maxn], vis[maxn];

int x[maxn], y[maxn], cnt;
void swp(int i, int j)
	x[++cnt] = i;  y[cnt] = j;
	swap(a[i],a[j]);
	p[a[i]] = i;  p[a[j]] = j;

void dfs(int i)
	if(a[a[i]]!=i)
		int j = a[i], k = p[i];
		swp(j,k); 
		vis[j] = vis[k] = 1;
		dfs(k);
	


int main()
	int n;  cin>>n;
	for(int i = 1; i <= n; i++)
		cin>>a[i];  p[a[i]] = i;
	
	
	int cc = 0;
	for(int i = 1; i <= n; i++)
		if(a[i]!=i)cc= max(cc, 1);
		if(a[a[i]]!=i)cc = 2;
	
	cout<<cc<<"\\n";
	
	while(1)
		int ok = 1;
		for(int i = 1; i <= n; i++)
			if(a[i]!=i)ok=0;break;
		if(ok==1)break;
		
		cnt = 0;
		for(int i = 1; i <= n; i++)
			if(!vis[i] && a[i]!=i)
				if(a[a[i]]==i)
					if(!vis[a[i]])
						vis[i] = vis[a[i]] = 1;
						swp(i,a[i]);
					
				else
					vis[i] = 1;
					dfs(i);	
				
			
		
		
		cout<<cnt<<" ";
		for(int i = 1; i <= cnt; i++)
			cout<<x[i]<<" "<<y[i]<<" ";
		cout<<"\\n";
		for(int i = 1; i <= n; i++)vis[i]=0;
	
	return 0;

以上是关于第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明),签到题4题的主要内容,如果未能解决你的问题,请参考以下文章

第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(银川),签到题5题

第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(银川),签到题5题

第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(上海),签到题5题

第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(上海),签到题5题

第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明),签到题4题

第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明),签到题4题