Contest 2050 and Codeforces Round #718 (Div. 1 + Div. 2)
A - Sum of 2050
如果这是一个由2050的倍数组成的数那么他肯定是可以被2050整除的,所以当他不能被2050整除时输出-1,当他可以被整除时最优情况就是从最大的倍数开始减去直至为零(就是整除后每位数字之和)
代码如下
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
ll xx(ll x)
{
ll ans=0;
while(x)
{
ans+=x%10;
x/=10;
}
return ans;
}
int main()
{
int t;cin>>t;
while(t--)
{
ll n;cin>>n;
if(n%2050) cout<<-1<<endl;
else
{
ll x=n/2050;
cout<<xx(x)<<endl;
}
}
return 0;
}
B - Morning Jogging
题意为给定一个二维数组每行的数字可以随意排序使得每列最小值之和最小
由题意可得我们可以先将所有数字存到一个一维数组中排序找到前m个小的数然后依次在二维数组中找到然后与改行的第x个数交换(x++) 交换后标记随后如果再次找到该数字不能再交换
代码如下
#include<iostream>
#include<algorithm>
using namespace std;
const int N=110;
int a[N][N],b[N*N];
bool vis[N][N];
int n,m;
int k;
int x1,y1;
int main()
{
int t;cin>>t;
while(t--)
{
int aa=0;
k=0;
cin>>n>>m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
cin>>a[i][j];
b[k++]=a[i][j];
}
sort(b,b+k);
// for(int i=0;i<k;i++) cout<<b[i]<<' ';
// cout<<endl;
for(int i=0;i<m;i++)
{
for(int x=0;x<n;x++)
for(int y=0;y<m;y++)
if(a[x][y]==b[i]&&!vis[x][y])
{
x1=x;
y1=y;
//vis[x][y]=true;
break;
}
vis[x1][aa]=true;
swap(a[x1][aa++],a[x1][y1]);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
cout<<a[i][j]<<' ';
cout<<endl;
}
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
vis[i][j]=false;
}
return 0;
}
C - Fillomino 2
由题意可得不可能推出是-1的情况,然后我们的想法就是往右开始扩展当要超出边界时开始向下扩展(是肯定的可行的)
代码如下
#include<iostream>
using namespace std;
const int N=510;
int a[N][N];
int n;
int k;
void dfs(int x,int y,int s,int u)
{
if(u==k||x<0||x>=n||y<0||y>=n) return;
if(a[x][y]!=0&&a[x][y]!=s) return;
a[x][y]=s;
k++;
dfs(x,y-1,s,u);
dfs(x+1,y,s,u);
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i][i];
for(int i=0;i<n;i++)
{
k=0;
dfs(i,i,a[i][i],a[i][i]);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<=i;j++)
cout<<a[i][j]<<' ';
cout<<endl;
}
return 0;
}