Codeforces 379 (Good Bye 2013)
379 C
题意
给你一个数组,现在可以将数组中的某个元素加上任意正整数,可以操作无限次,要求操作完后数组不能有重复元素,且元素之和最小。输出更改后的数组。
( \(1\le n\le 3·10^5\) )
Examples
Input
3
5 1 1
Output
5 1 2
Input
1
1000000000
Output
1000000000
解
先排序,维护一个变量mx,a[i]=max(a[i],mx),mx=a[i]+1。
379 D
题意
有两个串 \(s_1,s_2\) ,现在给你它们的长度,要求构造出这两个串,使 \(s_n\) 中"AC"的出现次数恰好为 \(x\)。
\(s_i=s_{i-2}+s_{i-1}(i≥3)\) (此处 \(+\) 为字符串连接)
( \(3 ≤ k ≤ 50,0 ≤ x ≤ 10^9,1 ≤ n, m ≤ 100\) )
Examples
Input
3 2 2 2
Output
AC
AC
Input
3 3 2 2
Output
Happy new year!
Input
3 0 2 2
Output
AA
AA
Input
4 3 2 1
Output
Happy new year!
Input
4 2 2 1
Output
Happy new year!
解
暴力分类讨论(X表示除A、C之外的任意字符)
1.
X...X
X...X
2.
C...X
X...A
3.
X...A
C...X
4.
X...X
C...A
5.
X...A
C...A
6.
C...A
C...A
Code 1
#include<bits/stdc++.h>
using namespace std;
long long f[103];
int k,x,n,m;
char s[103],t[103];
bool check(int mo){
int p=3;
while(p<k){
p++;
f[p]=f[p-2]+f[p-1];
if(mo==2){
if((p&1)==0)f[p]++;
}
else if(mo==4){
f[p]++;
}
else if(mo==5){
if(p&1)f[p]++;
}
}
return f[p]==x;
}
int main(){
scanf("%d%d%d%d",&k,&x,&n,&m);
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
f[1]=(i>>1),f[2]=(j>>1),f[3]=f[1]+f[2];
if(check(1)){
int l;
for(l=1;l<=i;l++)s[l]=(l&1?'A':'C');
for(;l<=n;l++)s[l]='B';
for(l=1;l<=j;l++)t[l]=(l&1?'A':'C');
for(;l<=m;l++)t[l]='B';
if(!((s[1]=='C'&&t[m]=='A')||(t[1]=='C'&&s[n]=='A')||(t[1]=='C'&&t[m]=='A'))){
puts(s+1),puts(t+1);
return 0;
}
}
if(i<=n-1&&j<=m-1){
f[1]=(i>>1),f[2]=(j>>1),f[3]=f[1]+f[2];
if(check(2)){
int l;
s[1]='C';
for(l=2;l<=i+1;l++)s[l]=(l&1?'C':'A');
for(;l<=n;l++)s[l]='B';
t[m]='A';
for(l=m-1;l>=m-j;l--)t[l]=((m-l)&1?'C':'A');
for(;l>=1;l--)t[l]='B';
if(s[n]!='A'&&t[1]!='C'){
puts(s+1),puts(t+1);
return 0;
}
}
f[1]=(i>>1),f[2]=(j>>1),f[3]=f[1]+f[2]+1;
if(check(3)){
int l;
s[n]='A';
for(l=n-1;l>=n-i;l--)s[l]=((n-l)&1?'C':'A');
for(;l>=1;l--)s[l]='B';
t[1]='C';
for(l=2;l<=j+1;l++)t[l]=(l&1?'C':'A');
for(;l<=m;l++)t[l]='B';
if(s[1]!='C'&&t[m]!='A'){
puts(s+1),puts(t+1);
return 0;
}
}
}
if(i==0&&j<=m-2){
f[1]=0,f[2]=(j>>1),f[3]=f[1]+f[2],f[4]=f[2]+f[3];
int p=4;
while(p<k){
p++;
f[p]=f[p-2]+f[p-1]+(p&1);
}
if(f[p]==x){
int l;
for(l=1;l<=n;l++)s[l]='B';
t[1]='C';
for(l=2;l<m;l++)t[l]=(l&1?'C':'A');
t[m]='A';
puts(s+1),puts(t+1);
return 0;
}
}
if(i<=n-1&&j<=m-2){
f[1]=(i>>1),f[2]=(j>>1),f[3]=f[1]+f[2]+1;
if(check(5)){
int l;
s[n]='A';
for(l=n-1;l>=n-i;l--)s[l]=((n-l)&1?'C':'A');
for(;l>=1;l--)s[l]='B';
t[1]='C';
for(l=2;l<=j+1;l++)t[l]=(l&1?'C':'A');
for(;l<m;l++)t[l]='B';
t[m]='A';
if(s[1]!='C'){
puts(s+1),puts(t+1);
return 0;
}
}
}
if(i<=n-2&&j<=m-2){
f[1]=(i>>1),f[2]=(j>>1),f[3]=f[1]+f[2]+1;
if(check(4)){
int l;
s[1]='C',s[n]='A';
for(l=2;l<=i+1;l++)s[l]=(l&1?'C':'A');
for(;l<n;l++)s[l]='B';
t[1]='C',t[m]='A';
for(l=2;l<=j+1;l++)t[l]=(l&1?'C':'A');
for(;l<m;l++)t[l]='B';
puts(s+1),puts(t+1);
return 0;
}
}
}
}
puts("Happy new year!");
return 0;
}
Code 2
#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long
#define rep(a) for(int a=0;a<2;a++)//0 在首位表示C,在末尾表示A,1则反之
using namespace std;
int F[105];
int dp[105];
int a,b,c,p1,p2,p3;
int k,x,n,m;
signed main(){
scanf("%lld%lld%lld%lld",&k,&x,&n,&m);
for(int i=0;i<=n/2;i++)
for(int r=0;r<=m/2;r++)
rep(a)
rep(b)
rep(c)
rep(d){
if(i*2+a+b>n||r*2+c+d>m)continue;
int cc=(b&&c),dd=(a&&d),ee=(d&&c);
dp[1]=i,dp[2]=r,dp[3]=i+r+cc;
for(int p=4;p<=k;p++){// 大力七维枚举
dp[p]=dp[p-2]+dp[p-1];
if((p%2==0)){if(dd)dp[p]++;}
else if(ee)dp[p]++;
}
if(dp[k]==x){
if(a==1)putchar('C');
for(int p=1;p<=i;p++)putchar('A'),putchar('C');
for(int p=i*2+a+1;p<=n-b;p++)putchar('X');
if(b)putchar('A');
putchar('\n');
if(c)putchar('C');
for(int p=1;p<=r;p++)putchar('A'),putchar('C');
for(int p=r*2+c+1;p<=m-d;p++)putchar('X');
if(d)putchar('A');
putchar('\n');
return 0;
}
}
puts("Happy new year!");
return 0;
}
Code 3
#include<bits/stdc++.h>
#define int long long
using namespace std;
int l[500005],r[500005],t[7][500005];
signed main()
{
int k,x,n,m;
scanf("%lld%lld%lld%lld",&k,&x,&n,&m);
l[1]=r[1]=1;
l[2]=r[2]=2;
t[3][1]=1;
t[4][2]=1;
for(int i=3;i<=k;i++)
{
t[1][i]=t[1][i-1]+t[1][i-2];//12
t[2][i]=t[2][i-1]+t[2][i-2];//21
t[3][i]=t[3][i-1]+t[3][i-2];//111
t[4][i]=t[4][i-1]+t[4][i-2];//12
t[5][i]=t[5][i-1]+t[5][i-2];//12
if(r[i-2]==1&&l[i-1]==2) t[1][i]++;
if(r[i-2]==2&&l[i-1]==1) t[2][i]++;
if(r[i-2]==2&&l[i-1]==2) t[5][i]++;
r[i]=r[i-1];
l[i]=l[i-2];
}
int xx=x;
for(int i=0;i<=n/2;i++)
{
int xxx=xx-t[3][k]*i;
if(xxx<0) break;
if(xxx%t[4][k]==0&&xxx/t[4][k]<=m/2)
{
for(int j=1;j<=i;j++)
{
printf("AC");
}
for(int j=i*2+1;j<=n;j++)
{
printf("B");
}
printf("\n");
for(int j=1;j<=xxx/t[4][k];j++)
{
printf("AC");
}
for(int j=xxx/t[4][k]*2+1;j<=m;j++)
{
printf("B");
}
printf("\n");
return 0;
}
}
n--,m--;
xx=x-t[1][k];
for(int i=0;i<=n/2;i++)
{
int xxx=xx-t[3][k]*i;
if(xxx<0) break;
if(xxx%t[4][k]==0&&xxx/t[4][k]<=m/2)
{
for(int j=1;j<=i;j++)
{
printf("AC");
}
for(int j=i*2+1;j<=n;j++)
{
printf("B");
}
printf("A\nC");
for(int j=1;j<=xxx/t[4][k];j++)
{
printf("AC");
}
for(int j=xxx/t[4][k]*2+1;j<=m;j++)
{
printf("B");
}
printf("\n");
return 0;
}
}
xx=x-t[2][k];
for(int i=0;i<=n/2;i++)
{
int xxx=xx-t[3][k]*i;
if(xxx<0) break;
if(xxx%t[4][k]==0&&xxx/t[4][k]<=m/2)
{
printf("C");
for(int j=1;j<=i;j++)
{
printf("AC");
}
for(int j=i*2+1;j<=n;j++)
{
printf("B");
}
printf("\n");
for(int j=1;j<=xxx/t[4][k];j++)
{
printf("AC");
}
for(int j=xxx/t[4][k]*2+1;j<=m;j++)
{
printf("B");
}
printf("A\n");
return 0;
}
}
n++,m--;
if(m>=0)
{
xx=x-t[5][k];
for(int i=0;i<=n/2;i++)
{
int xxx=xx-t[3][k]*i;
if(xxx<0) break;
if(xxx%t[4][k]==0&&xxx/t[4][k]<=m/2)
{
for(int j=1;j<=i;j++)
{
printf("AC");
}
for(int j=i*2+1;j<=n;j++)
{
printf("B");
}
printf("\nC");
for(int j=1;j<=xxx/t[4][k];j++)
{
printf("AC");
}
for(int j=xxx/t[4][k]*2+1;j<=m;j++)
{
printf("B");
}
printf("A\n");
return 0;
}
}
}
n-=2;
if(n>=0&&m>=0)
{
xx=x-t[1][k]-t[5][k];
for(int i=0;i<=n/2;i++)
{
int xxx=xx-t[3][k]*i;
if(xxx<0) break;
if(xxx%t[4][k]==0&&xxx/t[4][k]<=m/2)
{
printf("B");
for(int j=1;j<=i;j++)
{
printf("AC");
}
for(int j=i*2+1;j<=n;j++)
{
printf("B");
}
printf("A\nC");
for(int j=1;j<=xxx/t[4][k];j++)
{
printf("AC");
}
for(int j=xxx/t[4][k]*2+1;j<=m;j++)
{
printf("B");
}
printf("A\n");
return 0;
}
}
xx=x-t[2][k]-t[5][k];
for(int i=0;i<=n/2;i++)
{
int xxx=xx-t[3][k]*i;
if(xxx<0) break;
if(xxx%t[4][k]==0&&xxx/t[4][k]<=m/2)
{
printf("C");
for(int j=1;j<=i;j++)
{
printf("AC");
}
for(int j=i*2+1;j<=n;j++)
{
printf("B");
}
printf("B\nC");
for(int j=1;j<=xxx/t[4][k];j++)
{
printf("AC");
}
for(int j=xxx/t[4][k]*2+1;j<=m;j++)
{
printf("B");
}
printf("A\n");
return 0;
}
}
xx=x-t[1][k]-t[2][k]-t[5][k];
for(int i=0;i<=n/2;i++)
{
int xxx=xx-t[3][k]*i;
if(xxx<0) break;
if(xxx%t[4][k]==0&&xxx/t[4][k]<=m/2)
{
printf("C");
for(int j=1;j<=i;j++)
{
printf("AC");
}
for(int j=i*2+1;j<=n;j++)
{
printf("B");
}
printf("A\nC");
for(int j=1;j<=xxx/t[4][k];j++)
{
printf("AC");
}
for(int j=xxx/t[4][k]*2+1;j<=m;j++)
{
printf("B");
}
printf("A\n");
return 0;
}
}
}
printf("Happy new year!\n");
return 0;
}
379 E
题意
有 \(n\) 个多边形,每个多边形有 \(k+2\) 个点
第 \(i\) 个点( \(2\le i\le k+1\) )的 \(x\) 坐标为 \(i-1\)
第 \(1\) 个点的坐标为 \((0,0)\)
第 \(k+2\) 个点的坐标为 \((k,0)\)
将这些多边形依次放到坐标系中,问每个多边形没有被其他多边形这遮住的部分的面积是多少。
( \(1\le n,k\le 300,误差\le 1e-4\) )
Examples
Input
2 2
2 1 2
1 2 1
Output
3.000000000000
0.500000000000
Input
1 1
1 1
Output
1.000000000000
Input
4 1
2 7
7 2
5 5
6 4
Output
4.500000000000
1.250000000000
0.050000000000
0.016666666667
解 1
用微积分思想
以一个极小的间隔暴扫对于一个\(x\)坐标能到达的最大高度,算出以该间隔为宽、高度为长的矩形面积,再减去上一次扫到的最大高度所构成的矩形的面积,与 \(0\) 取个 \(\max\) ,全部加起来即为答案。
Code 1
#include<bits/stdc++.h>
#define maxn 303
using namespace std;
double y[maxn][maxn],mx[2000003];
int n,k;
int main(){
scanf("%d%d",&n,&k);
int delta=1000000/k;
for(register int i=1;i<=n;i++){
for(register int j=0;j<=k;j++){
scanf("%lf",&y[i][j]);
}
double ans=0,yy,deltay;
for(register int j=0;j<k;j++){
yy=y[i][j];
deltay=(y[i][j+1]-y[i][j])/delta;
for(register int p=j*delta+1;p<=(j+1)*delta;p++){
yy+=deltay;
if(yy>mx[p]){
ans+=yy-mx[p];
mx[p]=yy;
}
}
}
printf("%.12lf\n",ans/delta);
}
return 0;
}
解 2
把坐标系分成 \(k\) 个矩形,每个做 \(n\) 次半平面交,切掉一块,用vector维护当前多边形的顶点。
时间复杂度 \(O(nk)\) 。
Code 2
#include<bits/stdc++.h>
#define maxn 303
#define E 1e-8
#define INF 1e18
using namespace std;
typedef double tp;
int sgn(tp x){return x<-E?-1:x>E;}
struct point{
tp x,y;
point(){}
point(tp _x,tp _y):x(_x),y(_y){}
void write(){printf("%.4lf %.4lf\n",x,y);}
bool operator <(const point& p)const{return sgn(x-p.x)==0?sgn(y-p.y)<0:sgn(x-p.x)<0;}
bool operator ==(const point& p)const{return sgn(x-p.x)==0&&sgn(y-p.y)==0;}
point operator +(const point& p)const{return point(x+p.x,y+p.y);}
point operator -(const point& p)const{return point(x-p.x,y-p.y);}
point operator *(tp k)const{return point(x*k,y*k);}
double norm()const{return x*x+y*y;}
};
typedef point Vec;
tp dot(const Vec& u,const Vec& v){return u.x*v.x+u.y*v.y;}
tp cross(const Vec& u,const Vec& v){return u.x*v.y-v.x*u.y;}
double dist(const point& p1,const point& p2){return sqrt(double(dot(p1-p2,p1-p2)));}
point inter(const point& P,const Vec& v,const point& Q,const Vec& w){
Vec u=P-Q;
if(sgn(cross(v,w))==0){
if(sgn(cross(Q-P,v))==0)return point(-INF,-INF); //chong he
return point(INF,INF); //ping xing
}
tp t=cross(w,u)/cross(v,w);
return P+v*t; //OK
}
double getS(const vector<point>& p){
double ans=cross(p[0],p[p.size()-1]);
for(int i=1;i<int(p.size());i++)ans+=cross(p[i],p[i-1]);
return abs(ans)*0.5;
}
bool onright(const point& P,const point& S,const point& T){
return sgn(cross(T-S,P-S))<0;
}
void change(vector<point>& a,const point& p1,const point& p2){
int l,r;
for(l=0;l<int(a.size())&&!onright(a[l],p1,p2);l++);
if(l>=int(a.size()))return;
for(r=l;r<int(a.size())&&onright(a[r],p1,p2);r++);
point a1=a[l-1],a2=a[l],a3=a[r-1],a4=a[r];
a.erase(a.begin()+l,a.begin()+r);
a.insert(a.begin()+l,inter(a1,a2-a1,p1,p2-p1));
a.insert(a.begin()+l+1,inter(a3,a4-a3,p1,p2-p1));
}
point a[maxn][maxn];
vector<point> p[maxn];
double S[maxn];
int n,k;
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
for(int j=0;j<=k;j++)scanf("%lf",&a[i][j].y),a[i][j].x=j;
}
for(int j=1;j<=k;j++){
p[j].push_back(point(j-1,1001));
p[j].push_back(point(j-1,0));
p[j].push_back(point(j,0));
p[j].push_back(point(j,1001));
S[j]=getS(p[j]);
}
for(int i=1;i<=n;i++){
double res=0;
for(int j=1;j<=k;j++){
double last=S[j];
change(p[j],a[i][j-1],a[i][j]);
S[j]=getS(p[j]);
res+=last-S[j];
}
printf("%.12lf\n",res);
}
return 0;
}