版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37868325/article/details/82903295
A:Xiongnu's Land (树状数组的差分数组)
题意:矩形沙漠(0,0)到(R,R),有n片绿洲,每个绿洲也是矩形,且不重叠。求一个整数分割线分割x,使得
1.左面与右面的绿洲面积尽量接近
2.若不能相等,就让左面的绿洲面积尽量的大
3.在绿洲面积差优先约束下,分割线尽量靠右
思路:
需要把面积是按x轴分割,所以要把面积落下来,落到x轴上,比如某绿洲的x范围是【L,R】,高为h,那么把就相当于直线从x=L移到x=L+1在这个矩形增加左面的面积为h,直线从L+1到L+2,,,R-1到R都分别为左面增加了h面积。(自己画个图想想)
对应的横坐标都加h,最后就枚举线的位置,求左面的面积,转化成求左面所有点的和、(不会树状数组差分数组的要先学学)
这样就转化成了区间更改,区间查询的求和问题,用树状数组的差分数组比较简单、
代码:
#include<bits/stdc++.h>
using namespace std;
long long T,N,R,aa,bb,c,d,l,r,A,B;
long long a[1000010],b[1000010],all;
int lowbit(int i)
{
return i&(-i);
}
void add(int i,long long x)
{
long long t=i-1;
while(i<1000005)
{
a[i]+=x;
b[i]+=x*t;
i+=lowbit(i);
}
}
long long sum(int i)
{
long long s=0;
while(i>0)
{
s+=a[i];
i-=lowbit(i);
}
return s;
}
long long sum2(int i)
{
long long s=0;
while(i>0)
{
s+=b[i];
i-=lowbit(i);
}
return s;
}
int main()
{
scanf("%lld",&T);
while(T--)
{
scanf("%lld%lld",&R,&N);
all=0;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=1;i<=N;i++)
{
scanf("%lld%lld%lld%lld",&aa,&bb,&c,&d);
l=min(R,aa+c);
r=max((long long)0,bb-d);
all+=(l-aa)*(bb-r);
add(aa+1,bb-r);
add(l+1,r-bb);
}
long long s,ss,bin=-1,ok;
for(int i=1;i<=R;i++)
{
A=i*sum(i);
B=sum2(i);
s=A-B;
ss=all-s;
if(s<ss) continue;
if(bin==-1) {bin=s;ok=i;}
else if(s>bin) break;
else ok=i;
}
printf("%lld\n",ok);
}
}
/*
5
1000
2
1 1 2 1
5 1 2 1
1000
1
1 1 2 1
*/
G、 Mysterious Antiques in Sackler Museum
思路:我的锅,,,读错题意读错了一个小时,,,都WA了三发,最后实在感觉没错,才会去看题意,然后队友发现题意错误。。。又重做的,,就是个暴力枚举判断题,,贼水。。
代码:
#include<bits/stdc++.h>
using namespace std;
int T;
struct Point
{
int x,y;
}pos[5];
int ok;
int pin(Point A,Point B)
{
if(A.x==B.x||A.x==B.y||A.y==B.x||A.y==B.y) return 1;
return 0;
}
int pi(Point A,Point B,Point C)
{
Point z;
if(A.x==B.x)
{
z.x=A.x;
z.y=A.y+B.y;
if(pin(z,C)) {ok=1;return 1;}
}
if(A.x==B.y)
{
z.x=A.x;
z.y=A.y+B.x;
if(pin(z,C)) {ok=1;return 1;}
}
if(A.y==B.x)
{
z.x=A.y;
z.y=A.x+B.y;
if(pin(z,C)) {ok=1;return 1;}
}
if(A.y==B.y)
{
z.x=A.y;
z.y=A.x+B.x;
if(pin(z,C)) {ok=1;return 1;}
}
return 0;
}
int main()
{
scanf("%d",&T);
while(T--)
{
ok=0;
for(int i=1;i<=4;i++)
{
scanf("%d%d",&pos[i].x,&pos[i].y);
}
for(int i=1;i<=3;i++)
for(int j=i+1;j<=4;j++)
{
for(int k=1;k<=4;k++)
{
if(k!=i&&k!=j) pi(pos[i],pos[j],pos[k]);
if(ok>=1) break;
}
if(ok>=1) break;
}
if(ok>=1) printf("Yes\n");
else printf("No\n");
}
}
/*
5
1 1 1 1 1 2 2 2
1 1 2 2 10 10 20 20
*/
思路:一个恶心的构造+模拟做出来。。。构造还算是比较好想的,但是!代码真的烦人!也没什么亮点。。。
代码:
#include<bits/stdc++.h>
using namespace std;
int a[505][505],n;
int main()
{
while(~scanf("%d",&n))
{
if(n==1) cout<<"1 1"<<endl<<"1 1"<<endl;
else if(n==2) cout<<"1 3"<<endl<<"1 1"<<endl<<"1 2 1 3"<<endl;
else if(n==3)
{
cout<<"2 3"<<endl;
cout<<"1 2\n1 3 2 3\n1 1 2 1 2 2"<<endl;
}
else if(n==4)
{
cout<<"2 5"<<endl;
cout<<"1 4\n1 5 2 5\n1 1 2 1 2 2\n1 2 1 3 2 3 2 4\n";
}
else
{
if(n%2==1)
cout<<n/2+1<<" "<<n<<endl;
else
cout<<n/2<<" "<<n+1<<endl;
cout<<"3 4\n1 4 1 5\n2 4 2 5 3 5\n2 2 2 3 3 3 3 2\n3 1 2 1 1 1 1 2 1 3\n";
if(n%2==0)
{
for(int i=6;i<=n;i++)
{
if(i==n) {
for(int j=i/2;j>=1;j--)
{
cout<<j<<" "<<i<<" ";
}
for(int j=1;j<i/2;j++)
cout<<j<<" "<<i+1<<" ";
cout<<i/2<<" "<<i+1<<endl;
}
else if(i%2==0)
{
for(int j=i/2-1;j>=1;j--)
{
cout<<j<<" "<<i<<" ";
}
for(int j=1;j<=i/2;j++)
cout<<j<<" "<<i+1<<" ";
cout<<i/2+1<<" "<<i+1<<endl;
}
else
{
for(int j=1;j<i;j++)
cout<<i/2+1<<" "<<j<<" ";
cout<<i/2<<" "<<i-1<<endl;
}
}
}
else
{
for(int i=6;i<=n;i++)
{
if(i%2==0)
{
for(int j=i/2-1;j>=1;j--)
{
cout<<j<<" "<<i<<" ";
}
for(int j=1;j<=i/2;j++)
cout<<j<<" "<<i+1<<" ";
cout<<i/2+1<<" "<<i+1<<endl;
}
else
{
for(int j=1;j<i;j++)
cout<<i/2+1<<" "<<j<<" ";
cout<<i/2<<" "<<i-1<<endl;
}
}
}
}
}
}
/*
5
1000
2
1 1 2 1
5 1 2 1
1000
1
1 1 2 1
*/
J:Osu! Master (暴力模拟)
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=10010;
struct Node
{
char ch;
int x;
}node[N];
int main()
{
int n;
while(~scanf("%d",&n))
{
int i,j;
for(i=1;i<=n;i++)
{
cin>>node[i].ch;
if(node[i].ch!='S')
cin>>node[i].x;
//system("pause");
}
bool f=0;
int pre=0,ans=0;
for(i=1;i<=n;i++)
{
if(node[i].ch=='S')
{
if(f)
ans++;
ans++;
pre=0;
f=0;
}
else
{
if(node[i].x<=pre)
{
ans++;
}
pre=node[i].x;
f=1;
}
}
if(node[n].ch=='C'||node[n].ch=='B')
ans++;
printf("%d\n",ans);
}
return 0;
}