2024 暑假友谊赛 3

 D - Derangement

如果当前数字和坐标数相等,那么就和 【下标+1】这个数位置互换,可以保证一定不会有错误。

#include<bits/stdc++.h>
#define endl '\n'
#define mk make_pair
#define int long long
using namespace std;
const int M=1e5 + 10;
const int N=2e6+10;
const int mod=1e9+7;
const int inf=LLONG_MAX/2;

int power(int a, int b,int p) {
	int res = 1;
	for (; b; b /= 2, a = 1LL * a * a % p) {
		if (b % 2) {
			res = 1LL * res * a % p;
		}
	}
	return res;
}


void solve() {
	
	int n;
	cin>>n;
	vector<int>a(n);
	map<int,int>u;
	for(int i=0;i<n;i++){
		cin>>a[i];
		u[a[i]]=i;
	}
	int sum=0;
	for(int i=0;i<n;i++){
		if(a[i]==i+1){
			swap(a[i],a[u[a[i]+1]]);
			sum++;
		}
	}
	cout<<sum<<endl;
}
signed main()
{	
	ios::sync_with_stdio(false), cin.tie(0),cout.tie(0); 
	int t = 1;
	//cin>>t;
	while (t--){
		solve();
	}
	return 0;
}

D. Divide by three, multiply by two

dfs深搜。

当时还没有睿抗,写出了这个题还以为会把深搜最短路之类的理解的好点。我是XX。

仔细看一遍题,保证一定有解,并且,解唯一(没说多组答案)

然后就好玩了,随便从原数列中抽一个数,向后向前延伸即可。

#include<bits/stdc++.h>
#define endl '\n'
#define mk make_pair
#define int long long
using namespace std;
const int M=1e5 + 10;
const int N=2e6+10;
const int mod=1e9+7;
const int inf=LLONG_MAX/2;

int power(int a, int b,int p) {
	int res = 1;
	for (; b; b /= 2, a = 1LL * a * a % p) {
		if (b % 2) {
			res = 1LL * res * a % p;
		}
	}
	return res;
}
int n;
int a[105];
vector<int>b;
int k;
map<int,int>u;
int kk=0;
bool bfs(int x){
	b.push_back(x);
	k++;
	if(k==n){
		for(int j=0;j<n;j++){
			cout<<b[j]<<" ";
		}
		return true;
	}
	if(u[x/3]!=0 and x%3==0){
		u[x/3]--;
		bfs(x/3);
	}
	if(u[x*2]!=0){
		u[x*2]--;
		bfs(x*2);
	}
	if(kk==1){
		return true;
	}else{
		return false;
	}
}


void solve() {
	
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=1;i<=n;i++){
		b.clear();
		k=0;
		for(int j=1;j<=n;j++){
			u[a[j]]++;
		}
		if(bfs(a[i])){
			
			return;
		}
	}
	
}
signed main()
{	
	ios::sync_with_stdio(false), cin.tie(0),cout.tie(0); 
	int t = 1;
	//cin>>t;
	while (t--){
		solve();
	}
	return 0;
}

Naming Company

Naming Company - CodeForces 794C - Virtual Judge

A,B 两人各有一个长度为 n 的,由小写字母构成的字符串 s , t ,还有一个长度为 n,初始时由 ? 组成的目标串 f 。

现在,A和B轮流进行如下操作:

 1.  在自己的字符串中选出一个字符 x 。
 2.  将 f 中的一个 ? 替换为 x 。
 3.  将 x 从自己的字符串中删去。
      当 f 中没有 ? 时游戏结束。

A 的目标是让 f  的字典序尽量小,而 B 的目标是让字典序尽量大。
现在设 A 为先手,你需要求出游戏结束后的 f 。

注意: s , t  中可能有多个重复的字符,每次只删除一个。

止损。由于在字符串越前面的字符,对字典序的影响就越大,所以,我们就尽可能地把对对方有利的字符往后放。
比如对于这组数据,A 就需要尽可能地把字典序大的字母往 f f f 的后面放,B 同理。

#include<bits/stdc++.h>
#define endl '\n'
#define mk make_pair
#define int long long
using namespace std;
const int M=1e5 + 10;
const int N=2e6+10;
const int mod=1e9+7;
const int inf=LLONG_MAX/2;

int power(int a, int b,int p) {
	int res = 1;
	for (; b; b /= 2, a = 1LL * a * a % p) {
		if (b % 2) {
			res = 1LL * res * a % p;
		}
	}
	return res;
}

char s[300005];

void solve() {
	
	int n;
	string s1;
	cin>>s1;
	string s2;
	cin>>s2;
	n=s1.size();
	sort(s1.begin(),s1.end());
	sort(s2.begin(),s2.end());
	reverse(s2.begin(),s2.end());
	int l=1,r=n;
	int x=0,y=0;
	int xx=n/2-1,yy=n/2-1;
	if(n%2==1){
		xx++;
	}
	int k=1;
	while(l<=r){
		if(k%2==1){
			if(s1[x]>=s2[y]){
				s[r]=s1[xx];
				xx--;
				r--;
			}else{
				s[l]=s1[x];
				x++;
				l++;
			}
		}else{
			if(s1[x]<s2[y]){
				s[l]=s2[y];
				l++;
				y++;
			}else{
				s[r]=s2[yy];
				r--;
				yy--;
			}
		}
		k++;
	}
	//ddeirt fedcba
	for(int i=1;i<=n;i++){
		cout<<s[i];
	}
	
}
signed main()
{	
	ios::sync_with_stdio(false), cin.tie(0),cout.tie(0); 
	int t = 1;
	//cin>>t;
	while (t--){
		solve();
	}
	return 0;
}

 D. AND, OR and square sum

 https://codeforces.com/problemset/problem/1368/D

看一个例子对于两个二进制数
1100101
0100100
AND结果:0100100 OR结果:1100101
如果两个二进制位都为1或0,AND OR 中结果不变还是1或0,如果一个是0 一个1,就会把1转到OR结果中AND中的那个位变为0。我将这个过程看作是一个让1往一个数(OR结果)分配的过程,所有二进制每个位总的个数不变,但通过上述操作可以让1集中到一个数上面,我们可以通过无限次操作总是拼出来一个大的数,相应的这个数花费的各个二进制位数减1,直到所有二进制位的个数耗尽,这样得出来的答案是最大的。

#include<bits/stdc++.h>
#define endl '\n'
#define mk make_pair
#define int long long
using namespace std;
const int M=1e5 + 10;
const int N=2e6+10;
const int mod=1e9+7;
const int inf=LLONG_MAX/2;

int power(int a, int b,int p) {
	int res = 1;
	for (; b; b /= 2, a = 1LL * a * a % p) {
		if (b % 2) {
			res = 1LL * res * a % p;
		}
	}
	return res;
}

void solve() {
	
	int n;
	cin>>n;
	vector<int>a(n);
	int wei[25]={0};
	for(int i=0;i<n;i++){
		cin>>a[i];
		int x=a[i];
		int sum=0;
		while(x!=0){
			int y=x&1;
			if(y){
				wei[sum]++;
			}
			sum++;
			x/=2;
		}
	}
	sort(a.begin(),a.end());
	reverse(a.begin(),a.end());
	int sum=0;
	for(int i=0;i<n;i++){
		int ans=0;
		for(int j=24;j>=0;j--){
			if(wei[j]!=0){
				ans+=(1<<j);
				wei[j]--;
			}
		}
		sum+=ans*ans;
	}
	
	
	cout<<sum<<endl;
	
}
signed main()
{	
	ios::sync_with_stdio(false), cin.tie(0),cout.tie(0); 
	int t = 1;
	//cin>>t;
	while (t--){
		solve();
	}
	return 0;
}

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值