【题解】Codeforces Round #792 (Div. 1 + Div. 2)A~D
目录A. Digit MinimizationB - Z mod X = CC. Column SwappingD - TrapsA. Digit Minimization题意:A,B两人做游戏,每一轮操作如下:A:选择两个不同的数位 swapB:删除最后一位数游戏结束时希望留下的最后一位数尽可能小思路:发现当这个数字只有两位时:输出的是个位的数大于两位时,输出最小的数code#include &
A. Digit Minimization
题意:
A,B两人做游戏,每一轮操作如下:
A:选择两个不同的数位 swap
B:删除最后一位数
游戏结束时希望留下的最后一位数尽可能小
思路:
发现当这个数字只有两位时:输出的是个位的数
大于两位时,输出最小的数
code
#include <bits/stdc++.h>
#define int long long
using namespace std;
int _;
void solve()
{
int n;
cin>>n;
int m=n;
vector<int>v;
while(n)
{
v.push_back(n%10);
n/=10;
}
int x=10,y=10;
for(int i=0;i<v.size();i++)
{
if(x>v[i])
{
y=x;
x=v[i];
}
else if(y>v[i])
{
y=v[i];
}
}
if(m<100)cout<<m%10<<endl;
else cout<<x<<endl;
}
signed main()
{
cin>>_;
while(_--)solve();
return 0;
}
B - Z mod X = C
题意:
对于1<=a<b<c<=1e8 找到合适的1<=x<y<z<=1e18
使得 x % y = a ,y % z = b, z % x = c
思路:
类似一个环,结合余数的特点,令商为1,0两种情况
x =a+b+c,y =b+c z=c
code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
int _;
void solve()
{
int a,b,c;
cin>>a>>b>>c;
cout<<a+b+c<<' '<<b+c<<' '<<c<<endl;
}
signed main()
{
cin>>_;
while(_--)solve();
return 0;
}
C. Column Swapping
题意:
给一个二维数组,选择两个位置 x,y 是的每行交换这两个位置上的元素,使得每行单调递增。
思路:
从第一行开始找,找到第一个乱序的行,并将乱序的列号存到一个数组里,如果这个数组的长度大于2则直接输出-1
如果长度等于0则不需要交换输出1
即可
否则交换每一行的这两个位置的元素,然后判断每一行是否是增序即可
code
#include <bits/stdc++.h>
using namespace std;
int _;
int n,m;
void solve()
{
cin>>n>>m;
vector<vector<int>>v(n,vector<int>(m));
vector<int>b;
vector<int>res;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>v[i][j];
for(int i=0;i<n&&res.empty();i++)
{
b=v[i];
cout<<endl;
sort(b.begin(),b.end());
for(int j=0;j<m;j++)
if(b[j]!=v[i][j])
res.push_back(j);
}
if(res.size()==0)
{
cout<<1<<' '<<1<<endl;
return;
}
else if(res.size()>2)
{
cout<<-1<<endl;
return;
}
for(int i=0;i<n;i++)
swap(v[i][res[0]],v[i][res[1]]);
for(int i=0;i<n;i++)
for(int j=1;j<m;j++)
if(v[i][j-1]>v[i][j])
{
cout<<-1<<endl;
return;
}
cout<<res[0]+1<<' '<<res[1]+1<<endl;
}
int main()
{
cin>>_;
while(_--)solve();
return 0;
}
D - Traps
题意:
现有 n 个陷阱,每个陷阱的代价是 ai ,你可以选择至多 k 个陷阱,跳过它们(即,不需要付出代价。)。如果选择跳过该陷阱,虽然当前陷阱不需要代价,但其他陷阱的代价均加 1 。问:至少需要多少代价,才能按顺序通过所有陷阱?
思路:
贪心,首先跳k次一定比不跳强(当后几次直接跳过时)
那么当当跳过第一个陷阱 i 时,总伤害减少 a[i]
后续陷阱伤害**+1**,后边还有k-1个陷阱,伤害减少k-1
第二次跳过,后边有 k-2 个陷阱,伤害减少 k-2 。
code
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+10;
int a[N];
int _;
int n,k;
void solve()
{
cin>>n>>k;
vector<int>v;
int res=0;
for(int i=1;i<=n;i++)cin>>a[i],res+=a[i];
for(int i=1;i<=n;i++)v.push_back(n-(a[i]+i));
sort(v.begin(),v.end());
for(int i=0;i<k;i++)res+=v[i];
//k-1,k-2...0
res-=k*(k-1)>>1;
cout<<res<<endl;
}
signed main()
{
cin>>_;
while(_--)solve();
return 0;
}
更多推荐
所有评论(0)