文章目录
这应该是站内相对详细的解题报告吧。
转载思路请@本人。
感想
关于自己
这一次裂开了。
第三题感觉思路是对的,如果按照题目说的边都是平行或垂直的话,那应该没问题。
但是我的程序跑出来发现有不平行也不垂直的边(可能吧)。
然后我就没法了,因为任意多边形我也不会。
关于平台
这难度标错了吧?第三题 “简单”?
第一题的样例二好像有问题。
像之前的倒水问题,那题真的不会,也是标着简单。
最近不打算出题,因为出题需要花费很大的精力。
这边建议出题人要写一份题解,在赛后公开,方便选手理解消化。
愿平台越做越好。
第一题 (难度:简单)
题目描述
鬼画符门莲台争夺战! 虽然鬼画符门是一个三流门派但是近期为了改善宗门弟子质量。 特意引进了进化莲台。 部分精英弟子会自己独占一块区域,或者几个精英弟子一块占领一块区域,他们占领的区域普通弟子不可以再占领,小艺作为普通弟子想知道自己还能占领哪些地方。莲台区域以1开始,由小到大编号表示。
100分做法
这一题样例二多给了一个数字。
这里可以直接覆盖区间,也可以用差分。不过差分更快。
C + + C++ C++代码如下:
#include<bits/stdc++.h>
using namespace std;
int a[10005]={},b[10005]={};
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int l,r;
scanf("%d%d",&l,&r);
a[l]++;
a[r+1]--;//差分第一步,l ++,r+1 --
}
for(int i=1;i<=m;i++)
{
a[i]+=a[i-1];//差分第二步,累加
if(a[i]==0)b[++b[0]]=i;//记录空位
}
printf("%d\n",b[0]);
for(int i=1;i<=b[0];i++)
{
printf("%d ",b[i]);
}
return 0;
}
第二题 (难度:入门)
题目描述
津津的零花钱一直都是自己管理。每个月的月初妈妈给津津 300 元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。 为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上 20% 还给津津。
因此津津制定了一个储蓄计划:每个月的月初,在得到妈妈给的零花钱后,如果她预计到这个月的月末手中还会有多于100 元或恰好 100 元,她就会把整百的钱存在妈妈那里,剩余的钱留在自己手中。 例如 11 月初津津手中还有 83 元,妈妈给了津津 300 元。津津预计 11 月的花销是 180 元,那么她就会在妈妈那里存 200 元,自己留下 183 元。到了 11月月末,津津手中会剩下 3 元钱。 津津发现这个储蓄计划的主要风险是,存在妈妈那里的钱在年末之前不能取出。有可能在某个月的月初,津津手中的钱加上这个月妈妈给的钱,不够这个月的原定预算。如果出现这种情况,津津将不得不在这个月省吃俭用,压缩预算。
现在请你根据2004年1月到12月每个月津津的预算,判断会不会出现这种情况。如果不会,计算到2004年年末,妈妈将津津平常存的钱加上20%还给津津之后,津津手中会有多少钱。
100分做法
题目很长,但很简单。就是每次存整百,判断会不会不够预算。
最后输出记得加上存款*1.2。
C + + C++ C++代码如下:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int sum=0,m=0;//m记录有多少个100元
for(int i=1;i<=12;i++)
{
sum+=300;
int x;
scanf("%d",&x);
if(x>sum)return 0*printf("-%d",i);//不够用了
sum-=x;
m+=sum/100;
sum%=100;
}
printf("%d\n",sum+m*120);
return 0;
}
第三题 (难度:qwq 真恶心 )
题目描述
给出一个简单多边形(没有缺口),它的边要么是垂直的,要么是水平的。要求计算多边形的面积。 多边形被放置在一个 X-Y 的卡笛尔平面上,它所有的边都平行于两条坐标轴之一。然后按逆时针方向给出各顶点的坐标值。所有的坐标值都是整数(因此多边形的面积也为整数)。
50分做法
这里只有50分做法qwq
将长度扩大一倍,然后把边描出来,将外面的用宽搜搜一边,然后记录面积。
如果四个点(一个边长为2的正方形)都没有被搜索过,则面积+1。
最后输出面积÷4即可。
手画了各种情况都没问题,就不知道错在哪。
C + + C++ C++代码如下:
#include<bits/stdc++.h>
using namespace std;
int fx[5]={0,-1,0,1,0},fy[5]={0,0,1,0,-1},b[2005][2005]={};
int a[200005][2]={},q[200005][2]={},d[1000005][2]={};
int n;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i][0],&a[i][1]);
a[i][0]+=405;
a[i][1]+=405;//防止负数
if(i==1)continue;
if(a[i][0]==a[i-1][0])
{
if(a[i][1]>a[i-1][1])q[i][0]=a[i][1]-a[i-1][1],q[i][1]=1;
else q[i][0]=a[i-1][1]-a[i][1],q[i][1]=3;
}
else
{
if(a[i][0]>a[i-1][0])q[i][0]=a[i][0]-a[i-1][0],q[i][1]=2;
else q[i][0]=a[i-1][0]-a[i][0],q[i][1]=4;
}
q[i][0]*=2;
}
int x=a[1][0],y=a[1][1];
b[x][y]=1;
for(int i=2;i<=n;i++)
{
for(int j=1;j<=q[i][0];j++)
{
x+=fx[q[i][1]];
y+=fy[q[i][1]];
b[x][y]=1;//画边
}
}
if(a[1][0]>x)swap(a[1][0],x);
if(a[1][1]>y)swap(a[1][1],y);
for(int i=a[1][0];i<=x;i++)
{
for(int j=a[1][1];j<=y;j++)
{
b[i][j]=1;//最后一条边
}
}
int h=0,t=1;
d[1][0]=1;d[1][1]=1;
while(h<t)//遍历外部
{
h++;
for(int i=1;i<=4;i++)
{
int xx=d[h][0]+fx[i],yy=d[h][1]+fy[i];
if(xx>=1&&xx<=1000&&yy>=1&&yy<=1000)
{
if(b[xx][yy]==0)
{
t++;
d[t][0]=xx;
d[t][1]=yy;
b[xx][yy]=2;
}
}
}
}
int ans=0;
for(int i=1;i<=950;i++)
{
for(int j=1;j<=950;j++)
{
if(b[i][j]!=2&&b[i+1][j]!=2&&b[i][j+1]!=2&&b[i+1][j+1]!=2)ans++;//记录面积
}
}
printf("%d\n",(int)ans/4);
return 0;
}
第四题(难度:中等)
题目描述
在n*m的地图上,存在一个喷水点,如果相邻的位置低于有水的地方,水就能流到相邻的某位置(即该格子需要其上下左右的格子海拔都比自身高的封闭图形才可以积水)。 已知各个格子的海拔高度,求积水的最大覆盖个格子数。
100分做法
一开始看错题了。这一题是立体的。
其实只需要从高到低往附近倒水即可。
C + + C++ C++代码如下:
#include<bits/stdc++.h>
using namespace std;
int a[1005][1005]={},ok[1005][1005]={},bz[1005][1005]={},d[1000005][2]={},fx[5]={0,-
1,0,1,0},fy[5]={0,0,1,0,-1};
int qwq[1005][1005][2]={};
int n,m,ans=0,tot;
void bfs(int x,int y,int z,int id)
{
if(ok[x][y]||a[x][y]>=z)return;
int h=0,t=1;
d[1][0]=x;
d[1][1]=y;
bz[x][y]=id;
while(h<t)
{
h++;
int ax=d[h][0],ay=d[h][1];
if(ax==0||ay==0||ax==n+1||ay==m+1)return;
for(int i=1;i<=4;i++)
{
int xx=ax+fx[i],yy=ay+fy[i];
if(a[xx][yy]<z)
{
if(bz[xx][yy]!=id)
{
bz[xx][yy]=id;
t++;
d[t][0]=xx;
d[t][1]=yy;
}
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(bz[i][j]==id)
{
ans=ans+z-a[i][j];
a[i][j]=z;
ok[i][j]=1;
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
qwq[a[i][j]][++qwq[a[i][j]][0][0]][0]=i;
qwq[a[i][j]][qwq[a[i][j]][0][0]][1]=j;
}
}
for(int i=1000;i>=1;i--)
{
for(int j=1;j<=qwq[i][0][0];j++)
{
int I=qwq[i][j][0],J=qwq[i][j][1];
for(int t=1;t<=4;t++)
{
bfs(I+fx[t],J+fy[t],a[I][J],++tot);
}
}
}
printf("%d\n",ans);
return 0;
}