前言
加起来400分……
本着作死的心态来作死的2天
SSL初一组物品栏:
KYX:rp药 *10(Day1 220’)
WCR:擦鼻涕的纸/包扎受伤脚的纸 *inf
MYD:永远喝不完的奶粉 *inf
WJ:中午温暖的床 *1
LYW:不知道有什么诡异的东西的QQ *1
Day1
[KYX使用了rp药,rp=inf]
[KYX使用了rp药,获得成就:rp药第一人]
[KYX使用了rp药,增益状态启动]
[MYD使用奶粉,rp++]
[中午WCR的脚底受伤,rp–,使用包扎受伤脚的纸,rp++]
[中午WJ使用它/他温暖的床,rp++]
[下午LYW使用诡异的QQ,rp=-inf,将对其Day 2成绩造成影响]
T1
一道让人瞎搞的水题,记不得题面了
除了推式子一切都好
code:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int n,sl,sh;
int a[2011][2011],i,j,ax[2*2011*2011],ay[2*2011*2011],tot;
int main()
{
freopen("map.in","r",stdin);
freopen("map.out","w",stdout);
scanf("%d",&n);
for (i=1;i<=n;i++) for (j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
if (i==1||j==1) continue;
a[i][n+1]+=a[i][j];
a[n+1][j]+=a[i][j];
}
if (a[1][1]!=0)
{
printf("1 1");
fclose(stdin);
fclose(stdout);
return 0;
}
sh=a[n][n+1]+a[n][1];
sl=a[n+1][n]+a[1][n];
int l=0,r=0;
for (i=2;i<=n-1;i++)
{
if ((a[i][n+1]+sh)%2!=a[i][1])
{
r++;
for (j=2;j<=n;j++)
{
ay[tot]=j;
ax[tot++]=i;
}
}
}
for (i=2;i<=n-1;i++)
{
if ((a[n+1][i]+sl)%2!=a[1][i])
{
l++;
for (j=2;j<=n;j++)
{
ay[tot]=i;
ax[tot++]=j;
}
}
}
if (l==n-2&&r==n-2)
{
printf("%d %d",n,n);
}
if (tot==n-1&&(l==0||r==0))
{
if (r==0) printf("1 %d",ay[tot-1]);
else printf("%d 1",ax[tot-1]);
}
if (tot==2*n-2&(l==1&&r==1))
{
printf("%d %d",ax[0],ay[tot-1]);
}
if (tot==(n-1)*(n-2)&&(r==0||l==0))
{
if (r==0) printf("1 %d",n);
else printf("%d 1",n);
}
if (tot==(n-1)*(n-2)+(n-1))
{
if (r==1&&l==n-2)
{
printf("%d %d",ax[0],n);
}
else
{
printf("%d %d",n,ay[tot-1]);
}
}
fclose(stdin);
fclose(stdout);
return 0;
}
T2
这题叫灌水……
为什么这是Day1最难的一题??(暗示Day1很水)
不开long long见祖宗
考场时想不出?暴力真香!!
40pts的暴力,貌似5mins?
正解是单调队列+二分查找
貌似我的单调队列很诡异?
ACcode:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
long long n,q,j,o,l,r,x,y,bl,br,cl,cr;
long long a[200001],s[200001],ans[200001];
struct f{
long long x,y;
} op;
bool cmp(f a,f b)
{
return a.x<=b.x;
}
vector<f> d[200001];
f b[200001],c[200001];
int main()
{
freopen("water.in","r",stdin);
freopen("water.out","w",stdout);
scanf("%lld%lld",&n,&q);
for (int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
s[i]=s[i-1]+a[i];
}
for (int i=1;i<=q;i++)
{
scanf("%lld%lld",&x,&y);
op.x=y,op.y=i;
d[x].push_back(op);
}
bl=br=n;
b[bl].x=0x7ffffff;
b[bl--].y=0;
for (int i=1;i<=n;i++)
{
cl=cr=n;
c[cl].x=0x7ffffff;
c[cl--].y=n+1;
while (bl<br&&b[bl+1].x<a[i]) bl++;
b[bl].x=a[i];
b[bl--].y=i;
for (int j=n;j>=i;j--)
{
while (cl<cr&&c[cl+1].x<a[j]) cl++;
c[cl].x=a[j];
c[cl--].y=j;
}
for (int j=0;j<d[i].size();j++)
{
op=d[i][j];
ans[op.y]=op.x*((c[upper_bound(c+cl,c+n+1,op,cmp)-c].y-1)-(b[upper_bound(b+bl,b+br,op,cmp)-b].y))-s[c[upper_bound(c+cl,c+n+1,op,cmp)-c].y-1]+s[b[upper_bound(b+bl,b+br,op,cmp)-b].y];
}
}
for (int i=1;i<=q;i++) cout<<ans[i]<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}
T3
大概是说把n个数两两(凉凉)配对,(>=l&<=r)求无法配对的个数
不会?
没事,增广路教他做人
实测考场时仅次于正解贪心,60pts(一看就是我的算法太诡异搞得出题人木有卡)
纪念增广路code:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int n,L,R,mn=0x7ffffff+1,mx,a[1000001],to[1000001],ans,x;
bool op[1000001];
bool dfs(int r)
{
for (int i=1;i<=n;i++)
{
if (a[i]+a[r]<=R&&a[i]+a[r]>=L&&op[i]==0)
{
if (to[i]==0)
{
to[i]=r,to[r]=i;
return 1;
}
else
{
op[i]=1;
int u=to[i];
op[u]=1;
to[i]=r,to[r]=i;
to[u]=0;
if (dfs(u)) return 1;
to[i]=u,to[u]=i,to[r]=0;
}
}
}
return 0;
}
int main()
{
freopen("match.in","r",stdin);
freopen("match.out","w",stdout);
scanf("%d%d%d",&n,&L,&R);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if (a[i]<mn) mn=a[i];
}
for (int i=1;i<=n;i++)
{
if (R-mn>=a[i]&&to[i]==0)
{
memset(op,0,sizeof(op));
op[i]=1;
x=i;
dfs(i);
}
}
for (int i=1;i<=n;i++)
{
if (to[i]==0) ans++;
}
printf("%d",ans);
fclose(stdin);
fclose(stdout);
return 0;
}
ACcodes:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int n,L,R,l,r,a[1000001],to[1000001],s;
int main()
{
freopen("match.in","r",stdin);
freopen("match.out","w",stdout);
scanf("%d%d%d",&n,&L,&R);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
sort(a+1,a+1+n);
r=n,l=1;
while (l<=r)
{
if (a[l]+a[r]<L) l++;
else if (a[l]+a[r]>R) r--;
else l++,r--,s+=2;
}
printf("%d",n-s);
fclose(stdin);
fclose(stdout);
return 0;
}//请诸位对比代码长度
T4
为啥dij和spfa不给分?是不是看不起最短路
其实就是并查集,不过查询和合并的顺序要搞一下
ACcodes:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int n,m,q,x,y,wy,ans,fa[200001],question[200001],b[200001];
struct f{
int x,y,z;
} a[610001];
int max(int x,int y)
{
if (x>y) return x;
else return y;
}
int find(int x)
{
if (fa[x]==x) return x;
else return fa[x]=find(fa[x]);
}
bool cmp(f a,f b)
{
if (a.z==b.z) return a.y>b.y;
return a.z<b.z;
}
int main()
{
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) b[i]=1,fa[i]=i;
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
}
scanf("%d",&q);
for (int i=1;i<=q;i++)
{
scanf("%d%d",&a[i+m].x,&a[i+m].z);
a[i+m].y=-i;
}
sort(a+1,a+1+m+q,cmp);
for (int i=1;i<=m+q;i++)
{
if (a[i].y>=0)
{
if (find(a[i].x)!=find(a[i].y)) b[find(a[i].y)]+=b[find(a[i].x)],fa[find(a[i].x)]=find(a[i].y);
}
else
{
question[-a[i].y]=b[find(a[i].x)];
}
}
for (int i=1;i<=q;i++) cout<<question[i]<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}
Day 2
[WCR脚修复完成,感冒,rp–,使用擦鼻涕的纸,rp++]
[MYD使用奶粉,rp++,增益状态启动]
[LYW减益状态启动]
[KYXrp药产生副作用,减益状态启动]
[中午WJ使用温暖的床,白日梦++,增益状态启动]
[WJ白日梦数量达到1,获得成就:与周公约会]
[周公吸走WJrp,WJrp=-1]
[周公传授WJ秘籍《乱卡精度》,需要增益状态使用]
[WJrp<0,增益取消,减益状态启动]
T1
有手就行
小四做过的题,忙里偷闲打了个快速幂
code:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int a[11];
int x=1;
int uyu(int x,int y)
{
int ans=1;
while (y!=0)
{
if (y%2==0)
{
y/=2;
x*=x;
x%=10;
}
else
{
y--;
ans*=x;
ans%=10;
}
}
return ans;
}
int main()
{
freopen("math.in","r",stdin);
freopen("math.out","w",stdout);
for (int i=1;i<=10;i++) cin>>a[i];
for (int i=8;i>=4;i-=2)
{
if (a[i]!=0)
{
a[i/2]+=a[i];
a[2]+=a[i];
a[i]=0;
}
}
int l=abs(a[2]-a[5]);
if (a[2]>a[5]) a[5]=0,a[2]=l;
else a[5]=l,a[2]=0;
for (int i=9;i>=2;i--)
{
x=(x*uyu(i,a[i]))%10;
}
cout<<x;
fclose(stdin);
fclose(stdout);
return 0;
}
T2
据说因为评测机太快(数据太水)导致我一个把bfs序看成dfs序的人AC,显然算法是一样的,但是bfs可以o(n),真是作死
code:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int t,n,fa[100001],tot,a[100001],i,zy[100001],zuo[100001],you[100001];
bool o;
inline int read()
{
int ans=0;
char u=getchar();
while (u>'9'||u<'0') u=getchar();
while (u<='9'&&u>='0') ans=ans*10+u-'0',u=getchar();
return ans;
}
bool dfs(int father)
{
if (father==0) return 0;
if (zy[father]==0)
{
if (a[i]<a[father])
{
zy[father]=1;
fa[i]=father;
zuo[father]=i;
return 1;
}
else
{
return 0;
}
}
if (zy[father]==1)
{
if (a[i]>a[father])
{
zy[father]=2;
fa[i]=father;
you[father]=i;
return 1;
}
else
{
if (dfs(zuo[father])==1)
{
return 1;
}
return 0;
}
}
if (zy[father]==2)
{
if (a[i]<a[father])
{
if (dfs(zuo[father])==1)
{
return 1;
}
}
if (a[i]>a[father])
{
if (dfs(you[father])==1)
{
return 1;
}
}
return 0;
}
}//作而不死,是为rp--
int main()
{
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
t=read();
while (t--)
{
memset(zy,0,sizeof(zy));
memset(fa,0,sizeof(fa));
n=read();
tot=1;
o=0;
a[1]=read();
for (i=2;i<=n;i++)
{
a[i]=read();
if (o==1) continue;
if (!dfs(1)) o=1;//Do you know DFS?
}
if (o) printf("NO\n");
else printf("YES\n");
}
fclose(stdin);
fclose(stdout);
return 0;
}
T3
最崩溃的是知道怎么做,但是就是打不出来
LCA+倍增+树上dp,先咕了,等学了LCA再做
T4
话说为啥dfs不给分?(5分都没有,真是作死)
实际上是开了spj(据说)的,那么我们先对半分,然后欧拉回路判断奇偶性,嗯,就这样了,嗯,嗯……
ACcode:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int n,a[1001][1001],b[1001][1001],c[1001][1001],o;
void dfs(int x)
{
if (o==0)
{
for (int i=1;i<=n;i++)
{
if (a[x][i])
{
a[x][i]=0;
o=1;
c[x][i]++;
dfs(i);
return;
}
}
}
else
{
for (int i=1;i<=n;i++)
{
if (a[i][x])
{
a[i][x]=0;
o=0;
b[i][x]++;
dfs(i);
return;
}
}
}
return;
}//发现a数组%2后就是一个邻接矩阵,不用白不用
int main()
{
freopen("matrix.in","r",stdin);
freopen("matrix.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++) for (int j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
b[i][j]=c[i][j]=a[i][j]/2;
a[i][j]%=2;
}
for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (a[i][j])
{
a[i][j]=0;
b[i][j]++;
o=0;
dfs(j);
break;
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++) printf("%d ",b[i][j]);
printf("\n");
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++) printf("%d ",c[i][j]);
printf("\n");
}
fclose(stdin);
fclose(stdout);
return 0;
}
后记
天知道我在哪个多重宇宙里,也许是AK的,也许是爆零的。 | ——WCR |
---|