A Tit for Tat
题意:给你一个n个数的数组,在k次操作下,每次可以选2个数,一个+1,一个-1,求如何让数组前面的数最小,后面的数最大。最小不能为0.
思路:模拟,把前面的数-掉都加在最后一个数上
#include<iostream>
using namespace std;
int n,k;
int s[110];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",&s[i]);
int j=1;
while(k)
{
if(j==n) break;
if(s[j]>k)
{
s[j]-=k;
s[n]+=k;
k=0;
}
else
{
s[n]+=s[j];
k-=s[j];
s[j]=0;
j++;
}
}
for(int i=1;i<=n;i++) printf("%d ",s[i]);
printf("
");
}
return 0;
}
B AGAGA XOOORRR
题意:给你n个数的数组,每次选取两个相邻的元素;然后移除它们,并在它们的位置放置一个整数等于这2个数的异或和,求是否能使数组的所有元素相等。并且至少留下2个元素。
思路:首先,一定要注意看是相邻
先发掘一下性质
1 最后不是2个相等的数就是3个相等的数
因为4个相等的数等于2个相等的数
2 相邻的数选
那么分别暴力枚举2个分割点和1个分割点
然后取异或和看看想不相等
查询的时候可以用前缀和来查询 o1
总体时间复杂度 otn^2 = 6e7
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 20010;
int n, m;
int g[N];
int s[N];
int main()
{
int T;
cin >> T;
while (T -- )
{
cin >> n;
for (int i = 1; i <= n; i ++ )
cin >> g[i];
s[1] = g[1];
for (int i = 2; i <= n; i ++ )
s[i] = s[i - 1] ^ g[i];
bool flag = false;
for (int i = 1; i <= n - 1; i ++ )
if (s[i] == (s[n] ^ s[i]))
{
flag = true;
break;
}
for (int i = 1; i <= n - 1; i ++ )
for (int j = i + 1; j <= n - 1; j ++ )
if (s[i] == (s[j] ^ s[i]) && s[i] == (s[n] ^ s[j]))
{
flag = true;
break;
}
if (flag) puts("YES");
else puts("NO");
}
return 0;
}
C Baby Ehab Partitions Again
题意:给你一个n个数的数组,求这个数组是否有2个序列,这2个序列必须包含这所有的n个数,并且每个数只包含一次,顺序随意。
并且定义,如果第一个子序列中元素的和等于第二个子序列中元素的和,则称这个数组是好的,
求是否可以通过删除最多一个数的情况下,使得它成为好的数组
思路:总和是ans的情况下 如果一开始不能表示出来 ans / 2的话 就输出0, 如果可以表示出来的话 就求暴力枚举删除的那一个数a[i],因为最多只删除一个数,然后看如果还是不能表示出来的话 直接输出break,当然前提是ans或者是ans-a[i] 必须是偶数 要不然也直接输出
能不能表示出来可以用01背包,每次判断选与不选,
总体时间复杂度 o n^2m = 2e7
m为数组总和
#include<bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define re register int
#define x first
#define y second
typedef long long ll ;
using namespace std;
const int N = 1e6 + 10 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
int n , m ;
int f[N] ;
int a[N] ;
int main()
{
cin >> n ;
int ans = 0 ;
for(int i = 1 ; i <= n ; i ++)
{
cin >> a[i] ;
ans += a[i] ;
}
f[0] = 1 ;
for(int i = 1 ; i <= n ; i ++)
{
for(int j = ans ; j >= a[i] ; j --)
{
if(f[j-a[i]] && !f[j])
{
f[j] = true ;
}
}
}
if(!f[ans/2] || ans % 2 != 0) puts("0");
else
{
for(int k = 1 ; k <= n ; k ++)
{
memset(f,0,sizeof f) ;
f[0] = 1 ;
for(int i = 1 ; i <= n ; i ++)
{
if(i == k) continue ;
for(int j = ans ; j >= 1 ; j --)
{
if(!f[j] && f[j-a[i]])
{
f[j] = true ;
}
}
}
if(!f[(ans-a[k]) / 2] || (ans - a[k]) % 2 != 0)
{
cout << 1 << endl;
cout << k << endl;
break;
}
}
}
return 0 ;
}