zoukankan      html  css  js  c++  java
  • Codeforces Round #713 (Div. 3) 题解

    本场链接: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
    ",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
    ",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
    ",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
    ",res);
    	}
        return 0;
    }
    
    

    G. Short Task

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

    • 对于(pin 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
    ",ans[n] == 0 ? -1 : ans[n]);
    	}
        return 0;
    }
    
  • 相关阅读:
    工作流 —— AWS
    ant design —— form 生成 嵌套json数据
    react 获取子组件的 state (转发)
    React 调用子组件的函数(函数)
    react js 组件传参(转发)
    链接脚本文件(.ld .lds)详解
    gcc ------ -ffunction-sections -fdata-sections -gc-sections 参数详解
    GNU ARM 汇编伪指令
    STM32 CM3/CM4 ------ startup.s 文件分析 ------ GCC RT-Thread Studio 版本
    __attribute__之section详解 ------ 把函数指定到具体某个section 之 RT-thread 实例详解
  • 原文地址:https://www.cnblogs.com/HotPants/p/14643849.html
Copyright © 2011-2022 走看看