Codeforces Round 983 (Div. 2)题解记录(A~D)

比赛链接:https://codeforces.com/contest/2032

A. Circuit

思路:最小的灯数,就是开了又关,答案为1的总数模二,最大灯数,分类讨论下,如果小于等于n就能开就开,否则在n的基础上消除几个多出来的

#include<iostream>
		#include<queue>D
		#include<map>
		#include<set>
		#include<vector>
		#include<algorithm>
		#include<deque>
		#include<cctype>
		#include<string.h>
		#include<math.h>
		#include<time.h>
		#include<random>
		#include<stack>
		#include<string>
		#define ll                        long long 
		#define lowbit(x) (x & -x)
		#define endl "\n"
		using namespace std;
		mt19937 rnd(time(0));
		const ll mod=1e9+7;
		ll ksm(ll x,ll y)
		{
			ll ans=1;
			while(y)
			{
				if(y&1)
				{
					ans=ans%mod*(x%mod)%mod;
				}
				x=x%mod*(x%mod)%mod;
				y>>=1;
			}
			return ans%mod%mod;
		}
		ll gcd(ll x, ll y)
		{
			if (y == 0)
				return x;
			else
				return gcd(y, x % y);
		}
		void fio()
		{
			ios::sync_with_stdio(0);
			cin.tie(0);
			cout.tie(0);
		}
		int main()
		{
			fio();
			ll t;
			cin>>t;
			while(t--)
			{
			ll n;
			cin>>n;
			ll cnt=0;
			for(ll i=1;i<=2*n;i++)
			{
				ll x;
				cin>>x;
				if(x==1)
				cnt++;
			}	
			if(cnt%2==0)
			{
				cout<<0<<" ";
			}
			else 
			cout<<1<<" ";
			if(cnt<=n)
			{
				cout<<cnt<<endl;
			}
			else 
			{
				cout<<n-(cnt-n)<<endl;
			}
			}
			return 0;
		}

B. Medians

思路:对于1特判下,其他的首先看k是否为1或者n,这个是变不成中位数的,因为数组一定给的是奇数个的
再思考如果是k是偶数,我直接前面1k-1,k,kn就行了,否则就k左右扩大一点,把偶数区间变奇数区间

#include<iostream>
		#include<queue>
		#include<map>
		#include<set>
		#include<vector>
		#include<algorithm>
		#include<deque>
		#include<cctype>
		#include<string.h>
		#include<math.h>
		#include<time.h>
		#include<random>
		#include<stack>
		#include<string>
		#define ll                        long long 
		#define lowbit(x) (x & -x)
		#define endl "\n"
		using namespace std;
		mt19937 rnd(time(0));
		const ll mod=1e9+7;
		ll ksm(ll x,ll y)
		{
			ll ans=1;
			while(y)
			{
				if(y&1)
				{
					ans=ans%mod*(x%mod)%mod;
				}
				x=x%mod*(x%mod)%mod;
				y>>=1;
			}
			return ans%mod%mod;
		}
		ll gcd(ll x, ll y)
		{
			if (y == 0)
				return x;
			else
				return gcd(y, x % y);
		}
		void fio()
		{
			ios::sync_with_stdio(0);
			cin.tie(0);
			cout.tie(0);
		}
		int main()
		{
			fio();
			ll t;
			cin>>t;
			while(t--)
			{
			ll n,k;
			cin>>n>>k;
			if(n==1)
			{
				cout<<1<<endl;
				cout<<1<<endl;
			}	
			else 
			{
				if(k==n||k==1)
				{
					cout<<-1<<endl;
					continue;
				}
				else 
				{
					if((n-k)%2==1)
					{
						cout<<3<<endl;
						cout<<1<<" "<<k<<" "<<k+1<<endl;
					}
					else 
					{
						cout<<3<<endl;
						cout<<1<<" "<<k-1<<" "<<k+2<<endl;
					}
				}
			}
			}
			return 0;
		}

C. Trinity
思路:一开始把题目理解成了不出现等于情况就行,心想这么难?随后又看了会题目,终于发现理解错题意了,
首先排序数组,从小到大一个个试做和并二分能到达的最远位置,随后答案是走一遍后它的前面消失的数加n-能到达的最远位置+1的和中取个最小的
因为数越小,越不符合题意,但是有时改大数也有代价更小

#include<iostream>
		#include<queue>
		#include<map>
		#include<set>
		#include<vector>
		#include<algorithm>
		#include<deque>
		#include<cctype>
		#include<string.h>
		#include<math.h>
		#include<time.h>
		#include<random>
		#include<stack>
		#include<string>
		#define ll                        long long 
		#define lowbit(x) (x & -x)
		#define endl "\n"
		using namespace std;
		mt19937 rnd(time(0));
		const ll mod=1e9+7;
		ll ksm(ll x,ll y)
		{
			ll ans=1;
			while(y)
			{
				if(y&1)
				{
					ans=ans%mod*(x%mod)%mod;
				}
				x=x%mod*(x%mod)%mod;
				y>>=1;
			}
			return ans%mod%mod;
		}
		ll gcd(ll x, ll y)
		{
			if (y == 0)
				return x;
			else
				return gcd(y, x % y);
		}
		void fio()
		{
			ios::sync_with_stdio(0);
			cin.tie(0);
			cout.tie(0);
		}
		ll a[2500000];
		ll b[2500000];
		int main()
		{
			fio();
			ll t;
			cin>>t;
			while(t--)
			{
				ll n;
				cin>>n;
				for(ll i=1;i<=n;i++)cin>>a[i];
				sort(a+1,a+1+n);
				ll l=0;
				ll ans=999999999999;
				ll cnt=0;
				for(ll i=1;i<=n;i++)
				{
					if(l==0)
					{
						l=a[i];
					}
					else 
					{
						ll u=l+a[i];
						ll k=lower_bound(a+1,a+1+n,u)-a;
						if(k==n+1)
						{
							ans=min(ans,cnt);
							break;
						}
						else 
						{
							ll op=n-k+1;
							ans=min(ans,cnt+op);
							cnt++;
							l=a[i];
						}
					}
				}
				//if(ans=)
				cout<<ans<<endl;
			}
			return 0;
		}

D. Genokraken

思路:用1去和后面的数询问,首先询问返回到0为止(在此区间返回1均直接把i的父亲设为0),随后当前这个数的父亲就是1了
随后从2开始逐步和当前的数询问,如果返回0则直接连,且值增大,否则值继续增大,这样一定可以满足第一个条件且询问数不会超过限定次数

#include<iostream>
		#include<queue>
		#include<map>
		#include<set>
		#include<vector>
		#include<algorithm>
		#include<deque>
		#include<cctype>
		#include<string.h>
		#include<math.h>
		#include<time.h>
		#include<random>
		#include<stack>
		#include<string>
		#define ll                        long long 
		#define lowbit(x) (x & -x)
		//#define endl "\n"
		using namespace std;
		mt19937 rnd(time(0));
		const ll mod=1e9+7;
		ll ksm(ll x,ll y)
		{
			ll ans=1;
			while(y)
			{
				if(y&1)
				{
					ans=ans%mod*(x%mod)%mod;
				}
				x=x%mod*(x%mod)%mod;
				y>>=1;
			}
			return ans%mod%mod;
		}
		ll gcd(ll x, ll y)
		{
			if (y == 0)
				return x;
			else
				return gcd(y, x % y);
		}
		void fio()
		{
			ios::sync_with_stdio(0);
			cin.tie(0);
			cout.tie(0);
		}
		ll query(ll x,ll y)
		{
			cout<<"?"<<" "<<x<<" "<<y<<endl;
			cout.flush();
			ll ans;
			cin>>ans;
			return ans;
		}
		ll a[2500000];
		ll b[2500000];
		int main()
		{
			fio();
			ll t;
			cin>>t;
			while(t--)
			{
				ll n;
				cin>>n;
				for(ll i=1;i<=n;i++)a[i]=0,b[i]=0;
				ll k=0;
				ll op=0;
				ll l=0;
				ll r=1;
				ll uo=1;
				ll cn=0;
				for(ll i=2;i<=n-1;i++)
				{
					if(op==0)
					{
						if(query(1,i))
						{
							a[i]=0;
							l=i;
							b[i]=i;
							uo=i;
						}
						else 
						{
							a[i]=1;
							op=1;
							cn=2;
							b[1]=r;
						}
					}
					else 
					{
						while(query(cn,i))cn++;
						a[i]=cn;cn++;
					}
				}
				cout<<"!"<<" ";
				for(ll i=1;i<=n-1;i++)
				{
					cout<<a[i]<<" ";
				}
				cout<<endl;

			}
			return 0;
		}
posted @ 2024-11-02 01:57  长皆  阅读(128)  评论(0编辑  收藏  举报