AtCoder Regular Contest 093
C题题意:给定N个点,求每次去掉一个点后,依次走过剩余每个点的距离和,最后需要返回起点。
C题题解:用一个数组B记录每个点和前面的点的距离,然后预处理出去掉当前点可以少走的距离,设k是当前点的前一个点和后一个点的距离,那么去掉当前点可以少走的距离就是b[i]+b[i+1]-k,那么结果就是所有和减去每个点可以少走的距离。
AC代码:
#include <bits/stdc++.h>
using namespace std;
#define _for(i,a,b) for(int i=a;i<=b;i++)
const int maxn = 100006;
long long n,a[maxn],b[maxn],sum,c[maxn];
int main(int argc, char const *argv[])
{
cin>>n;
_for(i,1,n)
{
cin>>a[i];
b[i]=abs(a[i]-a[i-1]);
sum+=b[i];
}
b[n+1]=abs(a[n]);
sum+=b[n+1];
_for(i,1,n)
{
int k = abs(a[i+1]-a[i-1]);
c[i]=b[i]+b[i+1]-k;
}
_for(i,1,n)
{
cout<<sum-c[i]<<endl;
}
return 0;
}
D题题意:给定A和B,在100*100的矩阵里构建正好存在A个'.'的联通块和B个'#'的联通块。
D题题解:构造就行了...解法很多,我每次用8个包围1个,然后将100*100的矩阵摆满。
AC代码:
#include <bits/stdc++.h>
using namespace std;
#define _for(i,a,b) for(int i=a;i<=b;i++)
const int maxn = 1006;
char s[maxn][maxn];
int n,m;
int main(int argc, char const *argv[])
{
cin>>n>>m;
if(n<=m)
{
int l = 1;
int r = 3;
_for(i,1,1000)
{
_for(j,1,1000)s[i][j]='.';
}
_for(i,1,n-1)
{
s[l][r]='#';
s[l+1][r]='#';
s[l+1][r-1]='#';
s[l][r-2]='#';
s[l+1][r-2]='#';
s[l-1][r]='#';
s[l-1][r-1]='#';
s[l-1][r-2]='#';
r+=4;
if(r>100)
{
r=2;
l+=4;
}
}
int k = 100;
int h = 100;
_for(i,1,m-n+1)
{
s[h][k]='#';
k-=2;
if(k<=0)
{
k=100;
h-=2;
}
}
cout<<100<<" "<<100<<endl;
_for(i,1,100)
{
_for(j,1,100)
{
cout<<s[i][j];
}
cout<<endl;
}
}
else
{
int l = 1;
int r = 3;
_for(i,1,1000)
{
_for(j,1,1000)s[i][j]='#';
}
_for(i,1,m-1)
{
s[l][r]='.';
s[l+1][r]='.';
s[l+1][r-1]='.';
s[l][r-2]='.';
s[l+1][r-2]='.';
s[l-1][r]='.';
s[l-1][r-1]='.';
s[l-1][r-2]='.';
r+=4;
if(r>100)
{
r=2;
l+=4;
}
}
int k = 100;
int h = 100;
_for(i,1,n-m+1)
{
s[h][k]='.';
k-=2;
if(k<=0)
{
k=100;
h-=2;
}
}
cout<<100<<" "<<100<<endl;
_for(i,1,100)
{
_for(j,1,100)
{
cout<<s[i][j];
}
cout<<endl;
}
}
}