The 4th Sichuan Provincial Collegiate Programming Contest
A | 水题 | 0:23:12 2Y 我们都看不懂题意,Moor老老实实敲了,然后WA了,然后我YY了个题意,好吧~ 题目好坑,有一句话是有误导性而且事实上没用== |
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
#include <map>
#include <cmath>
using namespace std;
const int maxn = 100005;
const int inf = 1111111111;
int main()
{
//freopen("in.txt","r",stdin);
int cas,a[3];
bool vis[15][15][15];
scanf("%d",&cas);
for(int ca = 1; ca<=cas;ca++)
{
scanf("%d%d%d",&a[0],&a[1],&a[2]);
memset(vis,0,sizeof(vis));
printf("Case #%d:\n",ca);
sort(a,a+3);
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
if(i!=j&&i!=k&&k!=j&&!vis[a[i]][a[j]][a[k]])
{
printf("%d %d %d\n",a[i],a[j],a[k]);
vis[a[i]][a[j]][a[k]]=1;
}
}
return 0;
}
C | 水题 | 0:43:47 4Y A得好心酸的水题,而且最后是三个人都想了这道题,奠定了整场比赛不管A多少题都是最后的基调 |
0:24:37:TLE while (q)没有q--,为毛测试的时候都没有发现。。。#论何其到底有多二# | ||
0:25:28:TLE 看错数据范围了== | ||
0:34:04:WA 想漏了一种情况 |
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int main()
{
int cas,n,m,q,x,ans;
scanf("%d",&cas);
for(int ca = 1; ca<=cas; ca++)
{
scanf("%d%d%d",&n,&m,&q);
printf("Case #%d:\n",ca);
while(q--)
{
scanf("%d",&x);
ans = 0;
if(n+m<x) ans =0;
else if(x-1<=n&&x-1<=m) ans = x-1;
else if(x-1<=n&&x-1>m) ans = m;
else if(x-1<=m&&x-1>n) ans = n;
else ans = n+m-x+1;
printf("%d\n",ans);
}
}
}
K | 中等水题 | 0:57:15 1Y 话说计算几何真是一道蛋蛋的忧桑嘛? 我们写不出叉积==(会好起来的……) |
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <set>
#define MAXN 20
using namespace std;
long long x[4],y[4];
long long l[4];
bool check()
{
int xx1,xx2,yy1,yy2;
xx1=x[0]-x[1],yy1=y[0]-y[1];
xx2=x[2]-x[1],yy2=y[2]-y[1];
return (xx1*xx2+yy2*yy1)==0;
}
long long cal(long long a,long long b)
{
return a*a+b*b;
}
int main()
{
//freopen("/home/moor/Code/input.txt","r",stdin);
int ncase;
scanf("%d",&ncase);
for(int h=1;h<=ncase;++h)
{
for(int i=0;i<4;++i)
scanf("%lld%lld",&x[i],&y[i]);
for(int i=0;i<4;++i)
l[i]=cal(x[i]-x[(i+1)%4],y[i]-y[(i+1)%4]);
printf("Case #%d: ",h);
if(l[0]==l[2]&&l[1]==l[3])
{
if(l[0]==l[1])
{
if(check())
printf("Square\n");
else printf("Diamond\n");
}
else if(check())
printf("Rectangle\n");
else printf("Parallelogram\n");
}
else printf("Others\n");
}
return 0;
}
J | LCA | 3:31:00 3Y |
我一开始的想法就是错的,然后骗着Moor屁颠屁颠地去敲了, 过了好久,敲完B才发现其本质 | ||
但是第一炮TLE了,找得我眼睛都瞎了, 两个邻接表加边的时候用的是同一个边计数器 | ||
其实就是增加一条边问图中任意两点间最短路有没有变化 题目给的是图是树都可以做 |
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <set>
#define MAXN 600010
using namespace std;
int ans[MAXN];
struct _tree
{
int he[MAXN],to[MAXN],nex[MAXN],l[MAXN],top;
int ahe[MAXN],ato[MAXN],anex[MAXN],al[MAXN],atop;
int fat[MAXN];
int toroot[MAXN];
bool vi[MAXN];
void add(int u,int v,int c)
{
to[top]=v;
nex[top]=he[u];
l[top]=c;
he[u]=top++;
}
int findfa(int h)
{
if(h!=fat[h])
fat[h]=findfa(fat[h]);
return fat[h];
}
void mul(int a,int b)
{
a=findfa(a),b=findfa(b);
if(a==b) return ;
fat[b]=a;
}
void init()
{
top=0;
atop=0;
for(int i=0;i<MAXN;++i)
fat[i]=i;
memset(he,-1,sizeof(he));
memset(ahe,-1,sizeof(ahe));
memset(vi,0,sizeof(vi));
}
void dfs(int h,int fa,int len)
{
toroot[h]=len;
for(int i=he[h];i!=-1;i=nex[i])
if(to[i]!=fa)
dfs(to[i],h,len+l[i]);
}
void aadd(int u,int v,int c)
{
ato[atop]=v;
anex[atop]=ahe[u];
al[atop]=c;
ahe[u]=atop++;
}
void tarjan(int h,int fa)
{
for(int i=he[h];i!=-1;i=nex[i])
if(to[i]!=fa)
{
tarjan(to[i],h);
fat[to[i]]=h;
}
for(int i=ahe[h];i!=-1;i=anex[i])
if(vi[ato[i]])
ans[al[i]]=(toroot[h]+toroot[ato[i]]-2*toroot[findfa(ato[i])]);
vi[h]=1;
}
}tr;
int query[100010][2];
int main()
{
//freopen("/home/moor/Code/input.txt","r",stdin);
int ncase,n,q;
int a,b,c,x,y,z;
scanf("%d",&ncase);
for(int h=1;h<=ncase;++h)
{
scanf("%d%d",&n,&q);
tr.init();
for(int i=0;i<n-1;++i)
{
scanf("%d%d%d",&a,&b,&c);
tr.add(a,b,c);
tr.add(b,a,c);
}
scanf("%d%d%d",&x,&y,&z);
memset(ans,0,sizeof(ans));
tr.dfs(1,-1,0);
for(int i=0;i<q;++i)
{
scanf("%d%d",&a,&b);
query[i][0]=a,query[i][1]=b;
tr.aadd(a,b,i);
tr.aadd(b,a,i);
}
for(int i=0;i<n;++i)
tr.aadd(i+1,x,i+q),
tr.aadd(x,i+1,i+q);
for(int i=0;i<n;++i)
tr.aadd(i+1,y,i+q+n),
tr.aadd(y,i+1,i+q+n);
printf("Case #%d:\n",h);
tr.tarjan(1,-1);
for(int i=0;i<q;++i)
{
int tmp;
a=query[i][1]-1+q;
b=query[i][0]+n-1+q;
tmp=ans[a]+ans[b]+z;
a=query[i][0]-1+q;
b=query[i][1]+n-1+q;
tmp=min(tmp,ans[a]+ans[b]+z);
ans[i]-=tmp;
}
for(int i=0;i<q;++i)
printf("%d\n",ans[i]>0?ans[i]:0);
}
return 0;
}
B | 想法题 | 2:51:06 4Y |
如果没记错的话,其实前面三炮都是在一句话上错了 long long s=(long long)n*(n+1)/2 | ||
感觉思想很经典,牵扯到位运算的很多题都是一位一位的看 |
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <set>
#define MAXN 60010
using namespace std;
int sum[32][MAXN],num[MAXN],n;
bool whi[32][MAXN];
double a[3];
void caland(int h)
{
long long cnt=0,prev=1;
long long ss=(long long)(n+1)*n/2;
for(int i=1;i<=n;++i)
{
if(whi[h][i]==0) prev=-1;
else
{
if(prev==-1) prev=i;
cnt+=i-prev+1;
}
}
a[0]+=(double)cnt/ss*(1<<h);
}
void calor(int h)
{
long long cnt=0,prev=1;
long long ss=(long long)(n+1)*n/2;
for(int i=1;i<=n;++i)
{
if(whi[h][i]==1) prev=-1;
else
{
if(prev==-1) prev=i;
cnt+=i-prev+1;
}
}
a[1]+=(double)(ss-cnt)/ss*(1<<h);
}
void calxor(int h)
{
long long cnt=0,odd=0,even=1;
long long ss=(long long)(n+1)*n/2;
for(int i=1;i<=n;++i)
{
if(sum[h][i]&1)
cnt+=even;
else cnt+=odd;
if(sum[h][i]&1) ++odd;
else ++even;
}
a[2]+=(double)cnt/ss*(1<<h);
}
int main()
{
//freopen("/home/moor/Code/output.txt","r",stdin);
int ncase;
scanf("%d",&ncase);
for(int h=1;h<=ncase;++h)
{
memset(sum,0,sizeof(sum));
memset(whi,0,sizeof(whi));
for(int i=0;i<3;++i)
a[i]=0;
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d",&num[i]);
for(int i=0,j=1;i<31;++i,j<<=1)
for(int k=1;k<=n;++k)
sum[i][k]=sum[i][k-1]+((num[k]&j)==j),whi[i][k]=(num[k]&j)==j;
for(int i=0;i<31;++i)
{
caland(i);
calor(i);
calxor(i);
}
printf("Case #%d: %.6f %.6f %.6f\n",h,a[0],a[1],a[2]);
}
}
D | 贪心 | 听了Moor的想法,感觉这道题不难的样子, 但是过的人好少的样子,一定是黎神太强了 |
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <set>
#define MAXN 600010
#define INF 1000000000
using namespace std;
long long num[MAXN];
int pos;
long long x[MAXN];
long long add(int h)
{
long long cnt=0;
num[h]+=x[h];
for(int i=h;i<pos;++i)
if(num[i]>1)
num[i+1]+=num[i]/2,
num[i]=num[i]&1;
else break;
if(num[pos]>0)
--num[pos];
else return x[h];
for(int i=pos;i>=h;--i)
cnt=cnt*2+num[i],
num[i]=0;
pos=-1;
return x[h]-cnt;
}
int main()
{
//freopen("/home/moor/Code/input.txt","r",stdin);
int ncase,n,a,tmp;
scanf("%d",&ncase);
for(int h=1;h<=ncase;++h)
{
scanf("%d",&n);
memset(x,0,sizeof(x));
memset(num,0,sizeof(num));
for(int i=0;i<n;++i)
{
scanf("%d%d",&a,&tmp);
x[a]+=tmp;
}
pos=-1;
for(int i=MAXN-1;i>=0;--i)
if(x[i])
{
if(pos!=-1)
x[i]-=add(i);
if(pos==-1)
{
if(x[i]&1)
pos=i;
}
}
printf("Case #%d: ",h);
if(pos==-1)
printf("0\n");
else
{
for(int i=0;i<=pos;++i)
num[i]=!num[i];
++num[0];
++num[pos];
for(int i=0;i<=pos;++i)
if(num[i]>1)
num[i+1]+=num[i]/2,
num[i]=num[i]&1;
for(int i=pos;i>=0;--i)
if(num[i]!=0)
{
for(;i>=0;--i)
printf("%d",(int)num[i]);
printf("\n");
break;
}
}
}
return 0;
}