A 题目链接:Problem - A - Codeforces
input:
5
3 2
5 6 0
1 1
7
5 3
7 0 4 0 4
4 2
2 7 3 4
3 3
1000000000 1000000000 999999997
output:
11
7
15
10
2999999997
题意:给定一个有n个数的数组a,给定一个数值k,允许对数组元素进行k次如下操作:若i mod k == j mod k,允许ai 和 aj交换
策略:水题一道,找到每种mod k相同的数中最大的值,加到ans里即可。
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=105;
int t,n,k;
ll a[N];
int main()
{
cin>>t;
while(t--)
{
cin>>n>>k;
memset(a,0,sizeof a);
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
ll maxn=-1;
ll ans=0;
for(int j=0;j<k;j++)
{
maxn=0;
for(int s=j;s<=n;s+=k)
{
if(a[s]>maxn)
maxn=a[s];
}
ans+=maxn;
}
cout<<ans<<endl;
}
return 0;
}
B 题目链接:Problem - B - Codeforces
input:
5
5 2 0
8 1 2
3 0 0
2 0 1
6 3 0
output:
1 1 4 4
-1
-1
2
-1
题意:共n个选手,标号1-n,从1,2选手开始,打车轮战,每场胜者和下一位选手打比赛,共n-1场比赛。现给出x和y,指每位选手的获胜次数为x场或y场,输出每场比赛的胜者是哪位选手。如果给定的x,y得不出本题结果,输出“-1”。
策略:首先,选手1和选手2其中之一一定是胜场为0,所以x和y一定有一个为0,如果不符合条件可以直接输出-1。因此所有胜场不为0的选手的胜场一定相同。比赛共有n-1场,,假设x不为0,则(n-1)% x == 0一定成立,若不符合条件,直接输出-1.
并且可以得出一个结论,x不为0的情况下,答案的输出规律是:从1开始,连续输出一组x个相同的数,该组数为1时,下一组数的大小为1+x+1,否则下一组数大小为x+i,构造出n-1个数位为止
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+1;
int T,n,x,y;
int main()
{
cin>>T;
while(T--)
{
cin>>n>>x>>y;
if((x!=0&&y!=0)||(x==0&&y==0))
{
cout<<-1<<endl;
continue;
}
if(x==0) swap(x,y);
if((n-1)%x)
{
cout<<-1<<endl;
continue;
}
int cnt=1;
for(int i=1;i<=(n-1)/x;i++)
{
for(int j=1;j<=x;j++)
{
cout<<cnt<<" ";
}
if(i==1)
{
cnt+=x+1;
}
else
{
cnt+=x;
}
}
cout<<endl;
}
return 0;
}
C 题目链接:Problem - C - Codeforces
input:
3
2
7 8
5
1 1000000000 3 0 5
1
0
output:
0
2
3 4
1 2
0
题意:给定长度为n的数组a,可对a中元素进行至多n次如下操作:对于下标l , r,如果al + ar是奇数,则ar = al,否则al = ar,试使用n次以内操作,实现将该数组元素转化为不下降序列。输出操作次数和每次操作的l,r
策略:这题很恶心人啊,思路有了直接刷刷就写出来了,没思路直接坐牢。团队经验比较少,赛时面对该题束手无策,想了一些比较逆天的贪心方法,漏洞过多,这里不再赘述。经高人指点,发现了该题的比较好的做法:首先将两端元素同化。然后中间的奇数或偶数都可以通过和两端元素进行操作来被两端元素同化了!!
下面贴出代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
ll a[N];
bool odd[N];
int t,n;
int main()
{
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
cout<<n-1<<endl;
if((a[1]+a[n])%2==0)
{
a[1]=a[n];
}
else
{
a[n]=a[1];
}
if(n==1)
{
continue;
}
cout<<1<<" "<<n<<endl;
for(int i=2;i<=n-1;i++)
{
if((a[i]+a[1])%2==0)
{
cout<<i<<" "<<n<<endl;
}
else
{
cout<<1<<" "<<i<<endl;
}
}
}
return 0;
}
D1 题目链接:Problem - D1 - Codeforces
input:
4
5 8 7
01001
00101
5 7 2
01000
11011
7 8 3
0111001
0100001
5 10 1
01100
01100
output:
8
-1
6
0
题意:给出两个长度为n的01串a,b,可以对串a进行两种操作:
1.花费x代价,将任意相邻两位的数0变1,1变0
2.花费y代价,将任意不相邻的两位的数0变1,1变0
请找出串a变为串b花费的最小代价,无解输出-1(easy version中x<=y 非常重要!!!!!)
策略:easy version的思路还是非常简单的。首先我们可以统计所有a和b不相同的数位,并用cnt计数。我们可以发现:
1. 当cnt % 2 == 1时,无解
2.当且仅当cnt == 2时且两个不同的数位相邻时,才有可能花费x代价纠正。此时比较x和2y的大小,若x > 2y,则可以连续两次纠正非相邻元素来完成目标
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e3+5;
string a,b;
bool judge[N];
int t,n;
ll x,y;
int main()
{
cin>>t;
while(t--)
{
cin>>n;
cin>>x>>y;
cin>>a>>b;
int cnt=0;
for(int i=0;i<n;i++)
{
judge[i]=false;
if(a[i]!=b[i])
{
judge[i]=1;
++cnt;
}
}
if(cnt%2==1)
{
cout<<-1<<endl;
continue;
}
if(cnt==2)
{
bool flag=0;
for(int i=0;i<n-1;i++)
{
if(judge[i]==1&&judge[i+1]==1)
{
flag=1;
}
}
if(flag)
{
if(x>2*y)
{
cout<<ll(2*y)<<endl;
continue;
}
else
{
cout<<x<<endl;
continue;
}
}
else
{
cout<<y<<endl;
}
}
else
{
cout<<ll(y*cnt/2)<<endl;
}
}
return 0;
}
最近忙,D2过段时间再补~~~