D - Derangement
如果当前数字和坐标数相等,那么就和 【下标+1】这个数位置互换,可以保证一定不会有错误。
cpp
#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。
仔细看一遍题,保证一定有解,并且,解唯一(没说多组答案)
然后就好玩了,随便从原数列中抽一个数,向后向前延伸即可。
cpp
#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轮流进行如下操作:
-
在自己的字符串中选出一个字符 x 。
-
将 f 中的一个 ? 替换为 x 。
-
将 x 从自己的字符串中删去。
当 f 中没有 ? 时游戏结束。
A 的目标是让 f 的字典序尽量小,而 B 的目标是让字典序尽量大。
现在设 A 为先手,你需要求出游戏结束后的 f 。
注意: s , t 中可能有多个重复的字符,每次只删除一个。
止损。由于在字符串越前面的字符,对字典序的影响就越大,所以,我们就尽可能地把对对方有利的字符往后放。
比如对于这组数据,A 就需要尽可能地把字典序大的字母往 f f f 的后面放,B 同理。
cpp
#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,直到所有二进制位的个数耗尽,这样得出来的答案是最大的。
cpp
#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;
}