Codeforces Round #630 (Div. 2)

晚上真给我打自闭了,,,,
人生中第一次还第二次爆零,睡了一大觉赶紧起来补题。

A. Exercising Walk

(自闭之源)
time limit per test:2 seconds
memory limit per test:512 megabytes

Alice has a cute cat. To keep her cat fit, Alice wants to design an exercising walk for her cat!

Initially, Alice’s cat is located in a cell (x,y) of an infinite grid. According to Alice’s theory, cat needs to move:

exactly a steps left: from (u,v) to (u−1,v);
exactly b steps right: from (u,v) to (u+1,v);
exactly c steps down: from (u,v) to (u,v−1);
exactly d steps up: from (u,v) to (u,v+1).
Note that the moves can be performed in an arbitrary order. For example, if the cat has to move 1 step left, 3 steps right and 2 steps down, then the walk right, down, left, right, right, down is valid.

Alice, however, is worrying that her cat might get lost if it moves far away from her. So she hopes that her cat is always in the area [x1,x2]×[y1,y2], i.e. for every cat’s position (u,v) of a walk x1≤u≤x2 and y1≤v≤y2 holds.

Also, note that the cat can visit the same cell multiple times.

Can you help Alice find out if there exists a walk satisfying her wishes?

Formally, the walk should contain exactly a+b+c+d unit moves (a to the left, b to the right, c to the down, d to the up). Alice can do the moves in any order. Her current position (u,v) should always satisfy the constraints: x1≤u≤x2, y1≤v≤y2. The staring point is (x,y).

You are required to answer t test cases independently.

Input
The first line contains a single integer t (1≤t≤103) — the number of testcases.

The first line of each test case contains four integers a, b, c, d (0≤a,b,c,d≤108, a+b+c+d≥1).

The second line of the test case contains six integers x, y, x1, y1, x2, y2 (−108≤x1≤x≤x2≤108, −108≤y1≤y≤y2≤108).

Output
For each test case, output “YES” in a separate line, if there exists a walk satisfying her wishes. Otherwise, output “NO” in a separate line.

You can print each letter in any case (upper or lower).

Example
input

6
3 2 2 2
0 0 -2 -2 2 2
3 1 4 1
0 0 -1 -1 1 1
1 1 1 1
1 1 1 1 1 1
0 0 0 1
0 0 0 0 0 1
5 1 1 1
0 0 -100 -100 0 100
1 1 5 1
0 0 -100 -100 100 0

output

Yes
No
No
Yes
Yes
Yes

Note
In the first test case, one valid exercising walk is
(0,0)→(−1,0)→(−2,0)→(−2,1)→(−2,2)→(−1,2)→(0,2)→(0,1)→(0,0)→(−1,0)

题意: 一个人遛狗,a,b,c,d表示向左右下上的步数,这些移动可以自由组合,那么就一来一回每次都折返(本人不知为什么做题时一直坚信一个方向走完了才能走下一个),那么要满足题意在一个矩形内,只需折返走完后坐标满足,前提是能够走出第一步。

AC代码:

#include 
using namespace std;
typedef long long ll;
int main(){
	int n;
	cin>>n;
	while(n--){
		int a,b,c,d,x,y,x1,y1,x2,y2;
		cin>>a>>b>>c>>d;
		cin>>x>>y>>x1>>y1>>x2>>y2;
		if(x==x1&&x==x2&&(a!=0||b!=0)){//判断左右方向能否走出第一步
			cout<<"NO"<<endl;
		}
		else if(y==y1&&y==y2&&(c!=0||c!=0)){//判断上下方向能否走出第一步
			cout<<"NO"<<endl;
		}
		else if(x-a+b>=x1&&x-a+b<=x2&&y-c+d>=y1&&y-c+d<=y2){//判断走完后是否还在范围里
			cout<<"YES"<<endl;
		}
		else cout<<"NO"<<endl;
	}
}

B. Composite Coloring

time limit per test:2 seconds
memory limit per test:512 megabytes

A positive integer is called composite if it can be represented as a product of two positive integers, both greater than 1. For example, the following numbers are composite: 6, 4, 120, 27. The following numbers aren’t: 1, 2, 3, 17, 97.

Alice is given a sequence of n composite numbers a1,a2,…,an.

She wants to choose an integer m≤11 and color each element one of m colors from 1 to m so that:

for each color from 1 to m there is at least one element of this color;
each element is colored and colored exactly one color;
the greatest common divisor of any two elements that are colored the same color is greater than 1, i.e. gcd(ai,aj)>1 for each pair i,j if these elements are colored the same color.
Note that equal elements can be colored different colors — you just have to choose one of m colors for each of the indices from 1 to n.

Alice showed already that if all ai≤1000 then she can always solve the task by choosing some m≤11.

Help Alice to find the required coloring. Note that you don’t have to minimize or maximize the number of colors, you just have to find the solution with some m from 1 to 11.

Input
The first line contains a single integer t (1≤t≤1000) — the number of test cases. Then the descriptions of the test cases follow.

The first line of the test case contains a single integer n (1≤n≤1000) — the amount of numbers in a sequence a.

The second line of the test case contains n composite integers a1,a2,…,an (4≤ai≤1000).

It is guaranteed that the sum of n over all test cases doesn’t exceed 104.

Output
For each test case print 2 lines. The first line should contain a single integer m (1≤m≤11) — the number of used colors. Consider colors to be numbered from 1 to m. The second line should contain any coloring that satisfies the above conditions. Print n integers c1,c2,…,cn (1≤ci≤m), where ci is the color of the i-th element. If there are multiple solutions then you can print any of them. Note that you don’t have to minimize or maximize the number of colors, you just have to find the solution with some m from 1 to 11.

Remember that each color from 1 to m should be used at least once. Any two elements of the same color should not be coprime (i.e. their GCD should be greater than 1).

Example
input

3
3
6 10 15
2
4 9
23
437 519 865 808 909 391 194 291 237 395 323 365 511 497 781 737 871 559 731 697 779 841 961

output

1
1 1 1
2
2 1
11
4 7 8 10 7 3 10 7 7 8 3 1 1 5 5 9 2 2 3 3 4 11 6

Note
In the first test case, gcd(6,10)=2, gcd(6,15)=3 and gcd(10,15)=5. Therefore, it’s valid to color all elements the same color. Note that there are other colorings which satisfy Alice’s requirement in this test case.

In the second test case there is only one element of each color, so the coloring definitely satisfies Alice’s requirement.

题意: 给你一串由n个非质数组成的数列,选m(m≤11)种颜色为这些数涂色,要求m种颜色都要用到,每个数涂一种颜色,如果两个数的最大公约数大于1则这两个数可以涂为相同的颜色,输出涂色方法。
思路:
(感谢来自codeforces@cjlu19zx的方法分享。)
因为1000个数,数据范围小,所以试试看把这些不是素数的数的因子全部找出来,打一张表。
打表代码:

#include 
using namespace std;
typedef long long ll;
int isprime(int a){
	for(int i=2;i<=sqrt(a);i++){
		if(a%i==0)return 0;
	}
	return 1;
}
int main(){
	set<int> s;
	for(int i=2;i<=1000;i++){
		if(isprime(i)){//素数直接跳过
			continue;
		}
		for(int j=2;j<=1000;j++){
			if(i%j==0){
				s.insert(j);//能被整除插入set,set中自动去重。
				break;
			}
		}
	} 
	set<int>::iterator it;
	for(it=s.begin();it!=s.end();it++){
		cout<<*it<<endl;
	}
} 

打印出来的表:2 3 5 7 11 13 17 19 23 29 31
惊喜的发现: 刚好11个
之后就上路了
你永远不知道这段丑陋的代码是我wa了几发得出来的

#include 
using namespace std;
typedef long long ll;
int biao[11]={2,3,5,7,11,13,17,19,23,29,31};
int main(){
	int n,k,a[10000]={0},b[10000]={0},max=0;
	cin>>n;
	while(n--){
		cin>>k;
		for(int i=0;i<k;i++){
			cin>>a[i];
			for(int j=0;j<11;j++){//得出每个数最小的公因数并保存
				if(a[i]%biao[j]==0){
					if(biao[j]==2)b[i]=1;
					else if(biao[j]==3)b[i]=2;
					else if(biao[j]==5)b[i]=3;
					else if(biao[j]==7)b[i]=4;
					else if(biao[j]==11)b[i]=5;
					else if(biao[j]==13)b[i]=6;
					else if(biao[j]==17)b[i]=7;
					else if(biao[j]==19)b[i]=8;
					else if(biao[j]==23)b[i]=9;
					else if(biao[j]==29)b[i]=10;
					else if(biao[j]==31)b[i]=11;
					if(b[i]>max)max=b[i];//求m
					break;
				}
			}
		}
		int conver[10000];//这个数组是用来处理中间或者前面有漏掉的数
		for(int i=0;i<k;i++){
			conver[i]=b[i];
		}
		sort(conver,conver+k);//排序后找到中间漏掉的数
//		for(int i=0;i
//			cout<
//		}
//		cout<<'\n';
		if(conver[0]!=1){//前段出现遗漏,就是第一个数不为1
			for(int i=0;i<k;i++){
				conver[i]-=(conver[0]);
				b[i]-=(conver[0]);
			}
			max-=(conver[0]);
		}
		for(int i=1;i<k;i++){
			while(conver[i]-conver[i-1]>1){//判断中间是否存在不连续
				for(int j=0;j<k;j++){
					if(b[j]>=conver[i]){//将原数组中所有大于等于不连续的后一个数的元素-1
						b[j]-=1;
					}
				}
				for(int j=i;j<k;j++){//同步操作
					conver[j]--;
				}
				max--;//所用的颜色减一
			}	
		}
		cout<<conver[k-1]<<endl;//这里的conver[k-1]可以用max替代
		for(int i=0;i<k;i++){
			cout<<b[i];
			if(i!=k-1)cout<<' ';
		}
		cout<<'\n';
	}
}

优化后的AC代码: 只对输入的数求公因数,省去了后面的“意外处理”。

#include 
using namespace std;
typedef long long ll;
int isprime(int a){
	for(int i=2;i<=sqrt(a);i++){
		if(a%i==0)return 0;
	}
	return 1;
}
int main(){
	int n;
	cin>>n;
	while(n--){
		int k,a[10000],b[10000],u=0;
		cin>>k;
		for(int i=0;i<k;i++){
			cin>>a[i];
		}
		set<int> s;
		for(int i=0;i<k;i++){
			for(int j=2;j<=100;j++){
				if(a[i]%j==0){
					s.insert(j);
					a[i]=j;//直接用最小因数替代
					break;
				}
			}
		} 
		set<int>::iterator it;
		for(it=s.begin();it!=s.end();it++){
			b[u]=*it;
			u++;
		}
//		for(int i=0;i
//			cout<
//		} 
		cout<<u<<endl;
		for(int i=0;i<k;i++){
			for(int j=0;j<u;j++){
				if(a[i]==b[j]){
					a[i]=j+1;
					break;
				}
			}
		}
		for(int i=0;i<k;i++){
			cout<<a[i];
			if(i!=k-1)cout<<' ';
		}
		cout<<'\n';
	}
}

能力时间有限,先解两题。

你可能感兴趣的:(Codeforces Round #630 (Div. 2))