暑假算法训练day8(cf的一些题的思路的整理)

目录

  • A. The Third Three Number Problem
  • B. Almost Ternary Matrix
  • C. The Third Problem
  • D. Productive Meeting
  • D. Fixed Point Guessing
  • D. Cyclic Rotation

A. The Third Three Number Problem

给定一个非负整数 n n n,求是否存在三个整数使得
( a ⊕ b ) + ( b ⊕ c ) + ( a ⊕ c ) = n (a⊕b)+(b⊕c)+(a⊕c)=n (ab)+(bc)+(ac)=n
根据性质:
0 ⊕ a = a 0⊕a=a 0a=a
我们可以构造三个数分别是:0,0,n/2即可解决此题

#include 
using namespace std;
const double pi = acos(-1.0);
#define x first
#define y second
#define LL long long 
#define int LL
#define pb push_back
#define all(v) (v).begin(),(v).end()
#define PII pair<int,int>
#define ll_INF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
#define debug(x) cerr << #x << ": " << x << endl
#define io ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
LL Mod(LL a,LL mod){return (a%mod+mod)%mod;}
LL lowbit(LL x){return x&-x;}//最低位1及其后面的0构成的数值
LL qmi(LL a,LL b,LL mod) {LL ans = 1; while(b){ if(b & 1) ans = ans * (a % mod) % mod; a = a % mod * (a % mod) % mod; b >>= 1;} return ans; }
int _;
int n;
void solve()
{
	cin>>n;
	if(n%2)cout<<-1<<endl;
	else 
	{
		cout<<0<<' '<<0<<' '<<n/2<<endl;
	} 
}
signed main()
{
    io;
 	cin>>_; 
	while(_--)
    solve();
    return 0;
}

B. Almost Ternary Matrix

给一个二维矩阵,有两种状态:黑与白。
定义它周围的点是其上下左右四个方向相邻的点,
给出n,m(偶数)别是矩阵长和宽,构造出一个满足每个点周围只能由两个与之状态不一样的点的矩阵。
暑假算法训练day8(cf的一些题的思路的整理)_第1张图片n=4,m=4
我们可以尝试这么画一个4*4
暑假算法训练day8(cf的一些题的思路的整理)_第2张图片
发现类似这样的存放是可以满足题目要求的

#include 
using namespace std;
const double pi = acos(-1.0);
#define x first
#define y second
#define LL long long 
#define int LL
#define pb push_back
#define all(v) (v).begin(),(v).end()
#define PII pair<int,int>
#define ll_INF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
#define debug(x) cerr << #x << ": " << x << endl
#define io ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
LL Mod(LL a,LL mod){return (a%mod+mod)%mod;}
LL lowbit(LL x){return x&-x;}//最低位1及其后面的0构成的数值
LL qmi(LL a,LL b,LL mod) {LL ans = 1; while(b){ if(b & 1) ans = ans * (a % mod) % mod; a = a % mod * (a % mod) % mod; b >>= 1;} return ans; }
int _;
int n,m;
const int N=110;
int g[N][N];
int func(int x,int y)
{
	int s=0;
	if(x%4==1||x%4==0)
	{
		if(y%4==1)s=1;
		else if(y%4==2)s=0;
		else if(y%4==3)s=0;
		else s=1;
	}
	else if(x%4==2||x%4==3)
	{
		if(y%4==1)s=0;
		else if(y%4==2)s=1;
		else if(y%4==3)s=1;
		else s=0;
	}
	return s;
}
void solve()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cout<<func(i,j)<<' ';
		}
		cout<<endl;
	}
}
signed main()
{
    io;
 	cin>>_; 
	while(_--)
    solve();
    return 0;
}

C. The Third Problem

给定一个长度为n的序列a,求与数组a相似的数组有多少个。
相似的定义如下:
如果一个数组与数组a在任意情况下分割,mex值都相等,那么称为相似。
这题也是看群里的思路写出来的,赛时写不出来。真的很弱%%%

刚开始固定0和1,从0和1的下标开始枚举,当出现2在0和1 之间时,那么可以放在0和1 之间的任意一个位置,由于2被加进来了,那么0和1 之间的位置减少一个,如果2出现在0和1 之外。那么就更新这个区间。重复上述操作。

#include 
using namespace std;
const double pi = acos(-1.0);
#define x first
#define y second
#define LL long long 
#define int LL
#define pb push_back
#define all(v) (v).begin(),(v).end()
#define PII pair<int,int>
#define ll_INF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
#define debug(x) cerr << #x << ": " << x << endl
#define io ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
LL Mod(LL a,LL mod){return (a%mod+mod)%mod;}
LL lowbit(LL x){return x&-x;}//最低位1及其后面的0构成的数值
LL qmi(LL a,LL b,LL mod) {LL ans = 1; while(b){ if(b & 1) ans = ans * (a % mod) % mod; a = a % mod * (a % mod) % mod; b >>= 1;} return ans; }
int _;
int n,m;
const int N=1e5+10;
const int mod=1e9+7;
int a[N];
int cnt[N];
void solve()
{
	cin>>n;
	for(int i=0;i<n;i++)cin>>a[i],cnt[a[i]]=i;
	int res=1,l=min(cnt[0],cnt[1]),r=max(cnt[0],cnt[1]);
	int len=r-l-1;
	for(int i=2;i<n-1;i++)
	{
		if(cnt[i]>=l&&cnt[i]<=r)res=Mod(res*len,mod),len--;
		else
		{
			if(l>cnt[i])len+=l-cnt[i]-1,l=cnt[i];
			if(cnt[i]>r)len+=cnt[i]-r-1,r=cnt[i];
		}
	}	
	cout<<res<<endl;
	
}
signed main()
{
    io;
 	cin>>_; 
	while(_--)
    solve();
    return 0;
}

D. Productive Meeting

给一个长度为n的数组a, a i a_i ai表示每个人的可以与其他人交流几次,输出方案。
贪心即可

#include 
using namespace std;
const double pi = acos(-1.0);
#define x first
#define y second
#define LL long long 
#define int LL
#define pb push_back
#define all(v) (v).begin(),(v).end()
#define PII pair<int,int>
#define ll_INF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
#define debug(x) cerr << #x << ": " << x << endl
#define io ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
LL Mod(LL a,LL mod){return (a%mod+mod)%mod;}
LL lowbit(LL x){return x&-x;}//最低位1及其后面的0构成的数值
LL qmi(LL a,LL b,LL mod) {LL ans = 1; while(b){ if(b & 1) ans = ans * (a % mod) % mod; a = a % mod * (a % mod) % mod; b >>= 1;} return ans; }
int _;
int n;
void solve()
{
	cin>>n;
	vector<PII>v;
	priority_queue<PII,vector<PII>,less<PII>>heap;
	for(int i=1;i<=n;i++)
	{
		 int x;
		 cin>>x;
		 if(x)heap.push({x,i});
	}
	while(heap.size()>1)
	{
		auto x=heap.top();
		heap.pop();
		auto y=heap.top();
		heap.pop();
		x.x--;
		y.x--;
		if(x.x>0)heap.push({x.x,x.y});
		if(y.x>0)heap.push({y.x,y.y});
		v.pb({min(x.y,y.y),max({x.y,y.y})});
	}
	cout<<v.size()<<endl;
	for(auto x:v)cout<<x.x<<' '<<x.y<<endl; 
}
signed main()
{
    io;
 	cin>>_; 
	while(_--)
    solve();
    return 0;
}

D. Fixed Point Guessing

这是一个交互题,也是我做的第一道交互题。
题目大意是在一个长度为n的数组a,元素可以两两互换。
找出那个不能交换的元素。
询问不超过15次。
首先想到二分,如果在某个区间内找到奇数个在这个区间的数,那么这个数一定在这个区间

#include 
using namespace std;
const double pi = acos(-1.0);
#define x first
#define y second
#define LL long long 
#define int LL
#define pb push_back
#define all(v) (v).begin(),(v).end()
#define PII pair<int,int>
#define ll_INF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
#define debug(x) cerr << #x << ": " << x << endl
#define io ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
LL Mod(LL a,LL mod){return (a%mod+mod)%mod;}
LL lowbit(LL x){return x&-x;}//最低位1及其后面的0构成的数值
LL qmi(LL a,LL b,LL mod) {LL ans = 1; while(b){ if(b & 1) ans = ans * (a % mod) % mod; a = a % mod * (a % mod) % mod; b >>= 1;} return ans; }
int _;
int n;
bool check(int l,int mid)
{
	int res=0;
	cout<<"? "<<l<<' '<<mid<<endl;
	for(int i=l;i<=mid;i++)
	{
		int x;
		cin>>x;
		if(x<l||x>mid)res++;
	}
	return ((mid-l+1-res)&1);
}
void solve()
{
	cin>>n;
	int l=1,r=n;
	while(l<r)
	{
		int mid=l+r>>1;
		if(check(l,mid))r=mid;
		else l=mid+1;
	}
	cout<<"! "<<l<<endl;
}
signed main()
{
    io;
 	cin>>_; 
	while(_--)
    solve();
    return 0;
}

D. Cyclic Rotation

#include 
using namespace std;
const double pi = acos(-1.0);
#define x first
#define y second
#define LL long long 
#define int LL
#define pb push_back
#define all(v) (v).begin(),(v).end()
#define PII pair<int,int>
#define ll_INF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
#define debug(x) cerr << #x << ": " << x << endl
#define io ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
LL Mod(LL a,LL mod){return (a%mod+mod)%mod;}
LL lowbit(LL x){return x&-x;}//最低位1及其后面的0构成的数值
LL qmi(LL a,LL b,LL mod) {LL ans = 1; while(b){ if(b & 1) ans = ans * (a % mod) % mod; a = a % mod * (a % mod) % mod; b >>= 1;} return ans; }
int _;
int n;
const int N=2e5+10;
int a[N],b[N];
int cnt[N];
void solve()
{
	cin>>n;
	memset(cnt,0,sizeof cnt);
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=n;i++)cin>>b[i];
	int ai=n,bi=n;
	b[n+1]=0;
	while(bi)
	{
		if(ai&&bi&&a[ai]==b[bi])
		{
			ai--,bi--;
			continue;
		}
		if(b[bi]==b[bi+1])
		{
			cnt[b[bi--]]++;
		}
		else if(cnt[a[ai]])
		{
			cnt[a[ai--]]--;
		}
		else
		{
			cout<<"NO"<<endl;
			return;
		}
	}
	cout<<"YES"<<endl;
	return;
}
signed main()
{
    io;
 	cin>>_; 
	while(_--)
    solve();
    return 0;
}

你可能感兴趣的:(算法,C++,codeforces,算法,c++,数据结构,贪心算法)