CodeForces - 1216C
无穷大的第一象限有三个长方形,给出分别的左下右上两顶点的坐标,第一个白的先放,后放两黑,问白还能不能看到
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int main(){
long long x1,x2,x3,x4,x5,x6,y1,y2,y3,y4,y5,y6;
cin>>x1>>y1>>x2>>y2;
cin>>x3>>y3>>x4>>y4;
cin>>x5>>y5>>x6>>y6;
long long s1,s2=0,s3=0,s4=0;
s1=(x2-x1)*(y2-y1);
long long m,n,p,q;
m=max(x1,x3);
n=max(y1,y3);
p=min(x2,x4);
q=min(y2,y4);
if(m<p&&n<q) s2=(p-m)*(q-n);
m=max(x1,x5);
n=max(y1,y5);
p=min(x2,x6);
q=min(y2,y6);
if(m<p&&n<q) s3=(p-m)*(q-n);
m=max(x1,max(x3,x5));
n=max(y1,max(y3,y5));
p=min(x2,min(x4,x6));
q=min(y2,min(y4,y6));
if(m<p&&n<q) s4=(p-m)*(q-n);
long long s=s1-s2-s3+s4;
if(s>0) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;
}
这题我和别人做的不太一样,他们都是分情况,我用的是面积法,将黑白的左下坐标取大,右上坐标取小,可以得到被黑覆盖的白的面积,我错了好几次,因为我忽略了一个最重要的情况,当两个黑的也有重叠时(如图)即绿色被算了两次,所以要再算 s4 加上,还有一个要注意的是如果两个int 类型相乘加过超过了int 要用long long表示时,需要把两个相乘的 int 也改为long long
CodeForces - 1216D
给出 n 种物品,初始数量相同为 x ,被偷后数量 ai ,被 y 人偷,每个人偷 z 件且偷一种,求 y 最小值和y 最小时的 z
#include<bits/stdc++.h>
using namespace std;
long long a[200010],b[200010];
int main()
{
int n;
cin>>n;
long long maxn=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
maxn=max(maxn,a[i]);
}
long long s=0,gcd=b[1];
for(int i=1;i<=n;i++)
{
b[i]=maxn-a[i];
s+=b[i];
if(b[i]) gcd=__gcd(b[i],gcd);
}
cout<<s/gcd<<" "<<gcd<<endl;
return 0;
}
这题我一开始认为排序后 ai 中,相邻差最小值为 z ,错的很明显,差为2,3,4……时,z 是1不是2
CodeForces - 1221B
n*n的棋盘,B( x , y )可以和( x+2 , y+1 ),( x+1 , y+2 )打架,随意放B,其余位置放W,要求打架次数尽可能多
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int main(){
int n;
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(i%2)
{
if(j%2) printf("W");
else printf("B");
}
else
{
if(j%2) printf("B");
else printf("W");
}
}
printf("\n");
}
return 0;
}
看了别人的才知道,奇数行奇数列放 B,偶数行偶数列放B,其余放W
CodeForces 1221D
n块篱笆高度 ai ,要求相邻两块篱笆高度不同,若相同可花 bi 使 ai 加一,问最少需要多少钱
#include<bits/stdc++.h>
using namespace std;
const int MaxN = 3e5 + 5;
typedef long long LL;
const LL inf = 0x3f3f3f3f3f3f3f3f;
int t,n;
LL a[MaxN],b[MaxN];
LL dp[MaxN][4];
int main()
{
int t;
cin>>t;
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld %lld",&a[i],&b[i]);
for(int i =1;i<=n;i++)
for(int j=0;j<4;j++)
dp[i][j]=inf;
for(int i=1;i<=n;i++)
{
for(int j=0;j<3;j++)
{
int cur=a[i]-a[i-1]+j;
for(int k=0;k<3;k++)
{
if(cur==k) continue;
dp[i][j] = min(dp[i][j],dp[i-1][k]+j*b[i]);
}
}
}
printf("%lld\n",min(min(dp[n][0],dp[n][1]),dp[n][2]));
}
return 0;
}