Codeforces Round #595 (Div. 3) a-c2題解

A. Yet Another Dividing into Teams

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

You are a coach of a group consisting of nn students. The ii-th student has programming skill aiai. All students have distinct programming skills. You want to divide them into teams in such a way that:

  • No two students ii and jj such that |ai−aj|=1|ai−aj|=1 belong to the same team (i.e. skills of each pair of students in the same team have the difference strictly greater than 11);
  • the number of teams is the minimum possible.

You have to answer qq independent queries.

Input

The first line of the input contains one integer qq (1≤q≤1001≤q≤100) — the number of queries. Then qq queries follow.

The first line of the query contains one integer nn (1≤n≤1001≤n≤100) — the number of students in the query. The second line of the query contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1001≤ai≤100, all aiai are distinct), where aiai is the programming skill of the ii-th student.

Output

For each query, print the answer on it — the minimum number of teams you can form if no two students ii and jj such that |ai−aj|=1|ai−aj|=1 may belong to the same team (i.e. skills of each pair of students in the same team has the difference strictly greater than 11)

Example

input

Copy

4
4
2 10 1 20
2
3 6
5
2 3 4 99 100
1
42

output

Copy

2
1
2
1

Note

In the first query of the example, there are n=4n=4 students with the skills a=[2,10,1,20]a=[2,10,1,20]. There is only one restriction here: the 11-st and the 33-th students can't be in the same team (because of |a1−a3|=|2−1|=1|a1−a3|=|2−1|=1). It is possible to divide them into 22 teams: for example, students 11, 22 and 44 are in the first team and the student 33 in the second team.

In the second query of the example, there are n=2n=2 students with the skills a=[3,6]a=[3,6]. It is possible to compose just a single team containing both students.

題意:

n個人要組成隊伍每個人不能跟他編號相鄰的人處於一隊(編號沒重複),問最小組多少隊

思路:、

以爲一個人的相鄰的人不能跟他組但是這個人可以跟除他以外任何人組所以答案只有兩種可能1和2,有相鄰則爲2無相鄰則爲1

模擬即可

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
int a[100009];
signed main() {
	int q;
	scanf("%d", &q);
	while(q--) {
		int n;
		scanf("%d", &n);
		for(int i = 0;i < n;++i) {
			scanf("%d", &a[i]);
		}
		sort(a, a+n);
		int flag = 0;
		for(int i = 1;i < n;++i) {
			if(a[i]-a[i-1] <= 1) {
				flag = 1;
			}
		}
		if(flag) {
			printf("2\n");
		}
		else {
			printf("1\n");
		}
	}
	return 0;
} 

B1. Books Exchange (easy version)

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

The only difference between easy and hard versions is constraints.

There are nn kids, each of them is reading a unique book. At the end of any day, the ii-th kid will give his book to the pipi-th kid (in case of i=pii=pi the kid will give his book to himself). It is guaranteed that all values of pipi are distinct integers from 11 to nn (i.e. pp is a permutation). The sequence pp doesn't change from day to day, it is fixed.

For example, if n=6n=6 and p=[4,6,1,3,5,2]p=[4,6,1,3,5,2] then at the end of the first day the book of the 11-st kid will belong to the 44-th kid, the 22-nd kid will belong to the 66-th kid and so on. At the end of the second day the book of the 11-st kid will belong to the 33-th kid, the 22-nd kid will belong to the 22-th kid and so on.

Your task is to determine the number of the day the book of the ii-th child is returned back to him for the first time for every ii from 11 to nn.

Consider the following example: p=[5,1,2,4,3]p=[5,1,2,4,3]. The book of the 11-st kid will be passed to the following kids:

  • after the 11-st day it will belong to the 55-th kid,
  • after the 22-nd day it will belong to the 33-rd kid,
  • after the 33-rd day it will belong to the 22-nd kid,
  • after the 44-th day it will belong to the 11-st kid.

So after the fourth day, the book of the first kid will return to its owner. The book of the fourth kid will return to him for the first time after exactly one day.

You have to answer qq independent queries.

Input

The first line of the input contains one integer qq (1≤q≤2001≤q≤200) — the number of queries. Then qq queries follow.

The first line of the query contains one integer nn (1≤n≤2001≤n≤200) — the number of kids in the query. The second line of the query contains nn integers p1,p2,…,pnp1,p2,…,pn (1≤pi≤n1≤pi≤n, all pipi are distinct, i.e. pp is a permutation), where pipi is the kid which will get the book of the ii-th kid.

Output

For each query, print the answer on it: nn integers a1,a2,…,ana1,a2,…,an, where aiai is the number of the day the book of the ii-th child is returned back to him for the first time in this query.

Example

input

Copy

6
5
1 2 3 4 5
3
2 3 1
6
4 6 2 1 5 3
1
1
4
3 4 1 2
5
5 1 2 4 3

output

Copy

1 1 1 1 1 
3 3 3 
2 3 3 2 1 3 
1 
2 2 2 2 
4 4 4 1 4 

題意:規定了每個人走到編號位置的下一步走向問你第i個人他走回自己的最短花費是多少

思路:我直接枚舉每步的走法成功就記錄不成功就--繼續直到都成功爲止

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define inf 0x3f3f3f3f
#define ll long long
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
int a[109];
int b[209];
int c[209];
int ans[209];
int main()
{
	int q;
	scanf("%d", &q);
	while(q--) {
		int n;
		memset(ans, 0, sizeof(ans));
		scanf("%d", &n);
		for(int i = 1;i <= n;++i) {
			scanf("%d", &c[i]);
		}
		for(int i = 1;i <= n;++i) {
			b[i] = i;
		}
		int day = 1;int sum = 0;
		while(1) {
			for(int i = 1;i <= n;++i) {
				a[i] = b[i];
			}
			for(int i = 1;i <= n;++i) {
				b[c[i]] = a[i];
			}
			for(int i = 1;i <= n;++i) {
				if(b[i] == i) {
					if(ans[i] == 0) {
						sum++;ans[i] = day;
					}			
				}
			}
			if(sum >= n) {
				break;
			}
			day++;
		}
		for(int i = 1;i <= n;++i) {
			printf("%d ", ans[i]);
		}
		putchar('\n');
	}
	return 0;
}

B2. Books Exchange (hard version)

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

The only difference between easy and hard versions is constraints.

There are nn kids, each of them is reading a unique book. At the end of any day, the ii-th kid will give his book to the pipi-th kid (in case of i=pii=pi the kid will give his book to himself). It is guaranteed that all values of pipi are distinct integers from 11 to nn (i.e. pp is a permutation). The sequence pp doesn't change from day to day, it is fixed.

For example, if n=6n=6 and p=[4,6,1,3,5,2]p=[4,6,1,3,5,2] then at the end of the first day the book of the 11-st kid will belong to the 44-th kid, the 22-nd kid will belong to the 66-th kid and so on. At the end of the second day the book of the 11-st kid will belong to the 33-th kid, the 22-nd kid will belong to the 22-th kid and so on.

Your task is to determine the number of the day the book of the ii-th child is returned back to him for the first time for every ii from 11 to nn.

Consider the following example: p=[5,1,2,4,3]p=[5,1,2,4,3]. The book of the 11-st kid will be passed to the following kids:

  • after the 11-st day it will belong to the 55-th kid,
  • after the 22-nd day it will belong to the 33-rd kid,
  • after the 33-rd day it will belong to the 22-nd kid,
  • after the 44-th day it will belong to the 11-st kid.

So after the fourth day, the book of the first kid will return to its owner. The book of the fourth kid will return to him for the first time after exactly one day.

You have to answer qq independent queries.

Input

The first line of the input contains one integer qq (1≤q≤10001≤q≤1000) — the number of queries. Then qq queries follow.

The first line of the query contains one integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the number of kids in the query. The second line of the query contains nn integers p1,p2,…,pnp1,p2,…,pn (1≤pi≤n1≤pi≤n, all pipi are distinct, i.e. pp is a permutation), where pipi is the kid which will get the book of the ii-th kid.

It is guaranteed that ∑n≤2⋅105∑n≤2⋅105 (sum of nn over all queries does not exceed 2⋅1052⋅105).

Output

For each query, print the answer on it: nn integers a1,a2,…,ana1,a2,…,an, where aiai is the number of the day the book of the ii-th child is returned back to him for the first time in this query.

Example

input

Copy

6
5
1 2 3 4 5
3
2 3 1
6
4 6 2 1 5 3
1
1
4
3 4 1 2
5
5 1 2 4 3

output

Copy

1 1 1 1 1 
3 3 3 
2 3 3 2 1 3 
1 
2 2 2 2 
4 4 4 1 4 

題意和從一樣

思路:摒棄以前的暴力思路用targin算法進行縮點然後求出每個縮點的縮點數即爲這個縮點的所有點的最小到達自己的時間就是環的周長,輸出每個點的縮點值的縮點數即可

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
const int maxn = 2e5+3;
int head[maxn], dfn[maxn], low[maxn];//dfn是時間戳low是最小的時間戳head頭
int chudu[maxn], rudu[maxn], id[maxn], all[maxn];//id是染色後的點 all是染色的點數 
bool instal[maxn];int cnt, tot, gg, n, m;//instal是判斷在不在棧中
stack<int>s;
struct Edge{
	int next, to;
}edge[maxn*20];//鏈式前向星存圖
inline void add(int x, int y) {
	cnt++;
	edge[cnt].to = y;
	edge[cnt].next = head[x];
	head[x] = cnt;
}
//鏈式前向星加邊
void targin(int x) {
	dfn[x] = low[x] = ++cnt;
	s.push(x);
	instal[x] = true;
	for(int i = head[x];i;i = edge[i].next) {
		int u = edge[i].to;
		if(!dfn[u]) {
			targin(u);
			low[x] = min(low[x], low[u]);
		}
		else if(instal[u]) low[x] = min(low[x], dfn[u]);
	}
	int k;
	if(low[x] == dfn[x]) {
		++gg;
		do{
			k = s.top();s.pop();
			instal[k] = false;
			id[k] = gg;all[gg]++;//id是染色gg是第一次的點把所有的一個聯通快的點縮成這個點all是存的縮點的點的數量
		}while(x != k);
	}
}//強連通
 
int main() {
	int q;
	scanf("%d", &q);
	while(q--) {
		//memset(all, 0,sizeof(all));
		memset(head,0 ,sizeof(head));
		memset(dfn, 0, sizeof(dfn));
		//memset(low, 0 ,sizeof(low));
		int n;
		scanf("%d", &n);
		int b;
		for(register int i = 1;i <= n;++i) {
			scanf("%d", &b);
			add(i, b);
		} 
		for(register int j = 1;j <= n;++j) {
			if(!dfn[j]) {
				targin(j);
			}
		}
		for(register int i = 1;i <= n;++i) {	
			printf("%d ", all[id[i]]);
		}
		putchar('\n');	
	}
	
	return 0;
}

C1. Good Numbers (easy version)

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

The only difference between easy and hard versions is the maximum value of nn.

You are given a positive integer number nn. You really love good numbers so you want to find the smallest good number greater than or equal to nn.

The positive integer is called good if it can be represented as a sum of distinct powers of 33 (i.e. no duplicates of powers of 33 are allowed).

For example:

  • 3030 is a good number: 30=33+3130=33+31,
  • 11 is a good number: 1=301=30,
  • 1212 is a good number: 12=32+3112=32+31,
  • but 22 is not a good number: you can't represent it as a sum of distinct powers of 33 (2=30+302=30+30),
  • 1919 is not a good number: you can't represent it as a sum of distinct powers of 33 (for example, the representations 19=32+32+30=32+31+31+31+3019=32+32+30=32+31+31+31+30 are invalid),
  • 2020 is also not a good number: you can't represent it as a sum of distinct powers of 33 (for example, the representation 20=32+32+30+3020=32+32+30+30 is invalid).

Note, that there exist other representations of 1919 and 2020 as sums of powers of 33 but none of them consists of distinct powers of 33.

For the given positive integer nn find such smallest mm (n≤mn≤m) that mm is a good number.

You have to answer qq independent queries.

Input

The first line of the input contains one integer qq (1≤q≤5001≤q≤500) — the number of queries. Then qq queries follow.

The only line of the query contains one integer nn (1≤n≤1041≤n≤104).

Output

For each query, print such smallest integer mm (where n≤mn≤m) that mm is a good number.

Example

input

Copy

7
1
2
6
13
14
3620
10000

output

Copy

1
3
9
13
27
6561
19683

題意:求出一個數n的不小於他的最小可以用一個3的幾次方加起來的形式的值

思路:模擬求出n的3進制然後判斷數組最後面的2的位置然後向前推都成爲0向後推有0就把它變成1讓後把後面的變成0即可

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
const int maxn = 1e6+3;
int st[maxn];
int main() {
	int q;
	scanf("%d", &q);
	while(q--) {
		memset(st, 0, sizeof(st));
		int n;
		scanf("%d", &n);
		int g = n;int r = 0;
		while(g) {
			st[r] = g%3;
			r++;
			g /= 3;
		}//求出3進制數組
		for(int i = r-1;i >= 0;--i) {
			if(st[i] == 2) {//找到2的位置
				int u1 = i+1;
				while(st[u1] != 0){//向前找0便向前邊把數組設成0
					st[u1] = 0;
					u1++;
				}
				st[u1] = 1;
				for(int j = 0;j <= i;++j) {
					st[j] = 0;
				}//向後全福成0
			}
		}
		if(st[r] == 1) {
			r++;
		}
		int sum = 0;
		for(int i = r-1;i >= 0;--i) {
			sum = sum*3 + st[i];
		}//3進制轉10進制
		printf("%d\n", sum);
	}
	return 0;
}

C2. Good Numbers (hard version)

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

The only difference between easy and hard versions is the maximum value of nn.

You are given a positive integer number nn. You really love good numbers so you want to find the smallest good number greater than or equal to nn.

The positive integer is called good if it can be represented as a sum of distinct powers of 33 (i.e. no duplicates of powers of 33 are allowed).

For example:

  • 3030 is a good number: 30=33+3130=33+31,
  • 11 is a good number: 1=301=30,
  • 1212 is a good number: 12=32+3112=32+31,
  • but 22 is not a good number: you can't represent it as a sum of distinct powers of 33 (2=30+302=30+30),
  • 1919 is not a good number: you can't represent it as a sum of distinct powers of 33 (for example, the representations 19=32+32+30=32+31+31+31+3019=32+32+30=32+31+31+31+30 are invalid),
  • 2020 is also not a good number: you can't represent it as a sum of distinct powers of 33 (for example, the representation 20=32+32+30+3020=32+32+30+30 is invalid).

Note, that there exist other representations of 1919 and 2020 as sums of powers of 33 but none of them consists of distinct powers of 33.

For the given positive integer nn find such smallest mm (n≤mn≤m) that mm is a good number.

You have to answer qq independent queries.

Input

The first line of the input contains one integer qq (1≤q≤5001≤q≤500) — the number of queries. Then qq queries follow.

The only line of the query contains one integer nn (1≤n≤10181≤n≤1018).

Output

For each query, print such smallest integer mm (where n≤mn≤m) that mm is a good number.

Example

input

Copy

8
1
2
6
13
14
3620
10000
1000000000000000000

output

Copy

1
3
9
13
27
6561
19683
1350851717672992089

思路:我的優化是提前在轉3進制時就知道2的最後的位置讓後求2前面的值乘以qpow(3,2)即可因爲後面都是0

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
const ll maxn = 1e4+3;
ll st[maxn];
ll qpow(ll x, ll y) {
	ll ans = 1;
	while(y) {
		if(y&1) {
			y--;
			ans = ans*x;
		}
		y>>=1;
		x*=x;
	}
	return ans;
}
signed main() {
	ll q;
	scanf("%lld", &q);
	while(q--) {
		memset(st, 0, sizeof(st));
		ll n;
		scanf("%lld", &n);		
		ll g = n;ll r = 0;
		ll min1 = -1;
		while(g) {
			st[r] = g%3;
			if(st[r] == 2) {
				min1 = r;
			}
			r++;
			g /= 3;
		}
		int hh = min1;
		if(min1 != -1) {
			while(st[hh] == 2) {
				st[hh] = 0;
				st[hh+1]++;
				hh++;
			}	
		}
		else{
			hh = 0;
		}
		if(st[r] == 1) {
			r++;
		}
		ll sum = 0;
		for(ll i = r-1;i >= hh;--i) {
			sum = sum*3 + st[i];
		}
		sum *= qpow(3, hh);
		printf("%lld\n", sum);
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章