ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #713 (Div. 3) 题解

2021-04-11 15:03:44  阅读:203  来源: 互联网

标签:forn int 题解 scanf 713 -- Div primes define


本场链接:Codeforces Round #713 (Div. 3)

A. Spy Detected!

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
typedef pair<int,int> pii;
#define x first
#define y second

const int N = 105;
int a[N];

int main()
{
	int T;scanf("%d",&T);
	while(T--)
	{
		int n;scanf("%d",&n);
		map<int,int> st;
		forn(i,1,n)
		{
			scanf("%d",&a[i]);
			++st[a[i]];
		}
		forn(i,1,n)
		{
			if(st[a[i]] == 1)	
			{
				printf("%d\n",i);
				break;
			}
		}
	}
    return 0;
}

B. Almost Rectangle

注意越界情况

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
typedef pair<int,int> pii;
#define x first
#define y second

const int N = 405;
char s[N][N];

int main()
{
	int T;scanf("%d",&T);
	while(T--)
	{
		int n;scanf("%d",&n);
		forn(i,1,n)	scanf("%s",s[i] + 1);
		
		int x1 = -1,y1,x2,y2;
		forn(i,1,n)	forn(j,1,n)
		{
			if(s[i][j] == '.')	continue;
			if(x1 == -1)	x1 = i,y1 = j;
			else	x2 = i,y2 = j;
		}
		
		if(x1 == x2)
		{
			if(x1 + 1 <= n)	s[x1 + 1][y1] = s[x2 + 1][y2] = '*';
			else	s[x1 - 1][y1] = s[x2 - 1][y2] = '*';
		}
		else if(y1 == y2)
		{
			if(y1 + 1 <= n)	s[x1][y1 + 1] = s[x2][y2 + 1] = '*';
			else	s[x1][y1 - 1] = s[x2][y2 - 1] = '*';
		}
		else	s[x2][y1] = s[x1][y2] = '*';
		
		forn(i,1,n)	printf("%s\n",s[i] + 1);
	}
    return 0;
}

C. A-B Palindrome

特别的:在第一轮循环的时候仅限于处于一边是问号一边不是的,因为做到一半可能需要的1会比0更多,但是从整体上来看填0会更好。放到后面处理,混在一起无法判断。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
typedef pair<int,int> pii;
#define x first
#define y second

const int N = 2e5+7;
char s[N];

int main()
{
	int T;scanf("%d",&T);
	while(T--)
	{
		int a,b;scanf("%d%d",&a,&b);
		int n = a + b,need0 = 0,need1 = 0;
		scanf("%s",s + 1);
		forn(i,1,n)	if(s[i] == '0')	++need0;else if(s[i] == '1')	++need1;
		need0 = a - need0,need1 = b - need1;
		if(need0 < 0 || need1 < 0)
		{
			puts("-1");
			continue;
		}

		bool ok = 1;
		forn(l,1,n / 2)
		{
			int r = n - l + 1;
			if(s[l] == s[r])
			{
				continue;
			}
			else
			{
				if(s[l] != '?')	swap(s[l],s[r]);
				if(s[l] != '?')	
				{
					ok = 0;
					break;
				}
				if(s[r] == '0')
				{
					if(!need0)	
					{
						ok = 0;
						break;
					}
					--need0;
					s[l] = '0';
				}
				else
				{
					if(!need1)
					{
						ok = 0;
						break;
					}
					--need1;
					s[l] = '1';
				}
			}
		}
		
		forn(l,1,n / 2)
		{
			int r = n - l + 1;
			if(s[l] == s[r] && s[l] == '?')
			{
				if(need1 >= need0)
				{
					if(need1 < 2)	
					{
						ok = 0;
						break;
					}
					need1 -= 2;
					s[l] = '1';s[r] = '1';
				}		
				else
				{
					if(need0 < 2)
					{
						ok = 0;
						break;
					}
					need0 -= 2;
					s[l] = '0';s[r] = '0';
				}
			}
		}
		
		if(n % 2)
		{
			if(s[(n + 1) / 2] == '?')
			{
				if(!need1 && !need0)
				{
					ok = 0;
					break;
				}
				else if(need1)
				{
					--need1;
					s[(n + 1) / 2] = '1';
				}
				else
				{
					--need0;
					s[(n + 1) / 2] = '0';
				}
			}
		}
		
		if(need1 || need0)	ok = 0;
		
		if(!ok)	puts("-1");
		else printf("%s\n",s + 1);
	}
    return 0;
}

D. Corrupted Array

特判:\(x = b[n + 1]\)的情形。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)

const int N = 2e5+7;
ll b[N];

int main()
{
	int T;scanf("%d",&T);
	while(T--)
	{
		int n;scanf("%d",&n);
		ll sum = 0;
		map<ll,int> st;
		forn(i,1,n + 2)	scanf("%lld",&b[i]),sum += b[i],++st[b[i]];
		
		bool ok = 0;
		ll x = -1;
		forn(i,1,n + 2)
		{
			if((sum - b[i]) % 2)	continue;
			--st[b[i]];
			if(st.count((sum - b[i]) / 2) && st[(sum - b[i]) / 2])
			{
				ok = 1;
				x = b[i];
				break;
			}
			++st[b[i]];
		}
		if(!ok)	puts("-1");
		else
		{
			bool xflag = 0,sflag = 0;
			forn(i,1,n + 2)
			{
				if(b[i] == x && !xflag)
				{
					xflag = 1;
					continue;
				}
				else if(b[i] == (sum - x) / 2 && !sflag)
				{
					sflag = 1;
					continue;
				}
				printf("%lld ",b[i]);
			}
			puts("");
		}
	}
    return 0;
}

E. Permutation by Sum

容易想到一个结论:求出一段区间能构造出来的最小答案和最大答案,在这之间的答案都可以构造出来。

对于\(n\)个数填进\(k\)个位置的情况:最小的总和是\((k + 1) * k / 2\),最大的情况对称。

倒着枚举每个数,只要能塞进去就塞。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
typedef pair<int,int> pii;
#define x first
#define y second

const int N = 505;
int ans[N];

int main()
{
	int T;scanf("%d",&T);
	while(T--)
	{
		int n,l,r,s;scanf("%d%d%d%d",&n,&l,&r,&s);
		forn(i,1,n)	ans[i] = 0;
		
		int k = r - l + 1;
		forr(i,1,n)
		{
			if(k > 0 && k * (2 * i + 1 - k) / 2 >= s && s - i >= k * (k - 1) / 2)
			{
				ans[l + k - 1] = i;
				--k;
				s -= i;
			}
		}
		
		if(k)
		{
			puts("-1");
			continue;
		}
		
		set<int> st;forn(i,l,r)	st.insert(ans[i]);
		int ga = 1;while(st.count(ga))	ga++;
		forn(i,1,n)
		{
			if(ans[i])	continue;
			ans[i] = ga;
			st.insert(ga);
			while(st.count(ga))	++ga;
		}
		forn(i,1,n)	printf("%d ",ans[i]);
		puts("");
	}
    return 0;
}

F. Education

显然枚举答案:考虑最终停留在的位置。维护当前手上的钱以及为了走到这个位置已经度过了多少天数。更新答案即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
typedef pair<int,int> pii;
#define x first
#define y second

const int N = 2e5+7;
ll a[N],b[N];

int main()
{
	int T;scanf("%d",&T);
	while(T--)
	{
		ll n,c;scanf("%lld%lld",&n,&c);
		forn(i,1,n)	scanf("%lld",&a[i]);
		forn(i,1,n - 1)	scanf("%lld",&b[i]);
		ll have = 0,res = 1e18,cur = 0;
		forn(i,1,n)
		{
			res = min(res,(c - have + a[i] - 1) / a[i] + cur);
			ll need = (b[i] - have + a[i] - 1) / a[i];
			have += a[i] * need - b[i];cur += need + 1;
		}	
		printf("%lld\n",res);
	}
    return 0;
}

G. Short Task

显然线性筛,考虑线性筛怎么求因数和:

  • 对于\(p\in primes\),显然有\(d[p] = p + 1\).

  • 对于\(i\),若\(i\%primes[j] == 0\)说明\(primes[j]\)不是\(i\)的最小因子,把因数和公式展开后可以得到结论:\(d[i * primes[j]] = d[i] * (primes[j] + 1)\)

  • 若\(i\%pirmes[j] != 0\)说明\(primes[j]\)是\(i\)的最小因子,考虑维护每个数对应的最小质因子的在约数和中的贡献:即\(1+p+p^2+...p^{w_1}\),其中\(p\)是\(i\)的最小质因子。则\(d[i * primes[j]] = d[i] / minp[i] * minp[i * primes[j]]\).

  • 维护\(minp\)部分:质数显然,若\(primes[j]\)不是\(i\)的最小质因子,那么\(minp[i * primes[j]] = primes[j] + 1\).否则\(minp[i * primes[j]] = minp[i] * primes[j] + 1\).

最后将还在范围内的答案计入即可。由于\(n \leq d(n) \leq 1e7\)所以筛到1e7即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
typedef pair<int,int> pii;
#define x first
#define y second

const int N = 1e7+7;
int primes[N],cnt,ans[N];
ll minp[N],dsum[N];
bool st[N];

void init()
{
	dsum[1] = 1;
	for(int i = 2;i < N;++i)
	{
		if(!st[i])	primes[cnt++] = i,dsum[i] = i + 1,minp[i] = i + 1;
		for(int j = 0;j < cnt && 1ll*primes[j] * i < N;++j)
		{
			st[primes[j] * i] = 1;
			if(i % primes[j])	dsum[i * primes[j]] = dsum[i] * (primes[j] + 1),minp[i * primes[j]] = primes[j] + 1;
			else
			{
				minp[i * primes[j]] = minp[i] * primes[j] + 1;
				assert(minp[i] != 0);
				dsum[i * primes[j]] = dsum[i] / minp[i] * minp[i * primes[j]];
				break;
			}
		}
	}
	forn(i,1,N - 1)	if(dsum[i] < N && !ans[dsum[i]])	ans[dsum[i]] = i;
}

int main()
{
	init();
	
	int T;scanf("%d",&T);
	while(T--)
	{
		int n;scanf("%d",&n);
		printf("%d\n",ans[n] == 0 ? -1 : ans[n]);
	}
    return 0;
}

标签:forn,int,题解,scanf,713,--,Div,primes,define
来源: https://www.cnblogs.com/HotPants/p/14643849.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有