您的位置:首页 > 其它

Asia - Changchun 5:00:00

2013-04-18 13:24 120 查看
这是我们分组后Dots_lzl小组第一次参加组队赛,也是很开心的一次,虽然只A了2道题目(本来应该是三道的,已经AC了,但是却说时间到了,居然说是因为比赛提前开始了几分钟,我们就是在最后几分钟A的呀,别的组WA20多次,我们5次过的题目,他居然封榜了),以下仅有C,E,K是我们组做的B -Bit Magic
本题很简单,明显的2-SAT的模版题。
这题是2-SAT。只不过模板写错了一点,多加了个分号,导致样例一直出不来。幸好调试之后发现,
修改一下,交上去1A,爽~~~~此题是做得最顺利的了。

现场赛的时候内存真的是无穷大啊,直接做31*500*2=31000个点的2-SAT就AC了。但是比赛结束后在ZOJ上就会MLE了~~~~~
要分开做,做31次的2-SAT就可以了~~~~~~

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;const int MAXN=1100;//bool visit[MAXN];
queue<int>q1,q2;
//vector建图方法很妙
vector<vector<int> >adj; //原图 //中间一定要加空格把两个'>'隔开
vector<vector<int> >radj;//逆图
vector<vector<int> >dag;//缩点后的逆向DAG图
int n,m,cnt;int id[MAXN],order[MAXN],ind[MAXN];//强连通分量,访问顺序,入度void dfs(int u)
{
visit[u]=true;
int i,len=adj[u].size();
for(i=0;i<len;i++)
if(!visit[adj[u][i]])
dfs(adj[u][i]);
order[cnt++]=u;
}
void rdfs(int u)
{
visit[u]=true;
id[u]=cnt;
int i,len=radj[u].size();
for(i=0;i<len;i++)
if(!visit[radj[u][i]])
rdfs(radj[u][i]);
}
void korasaju()
{
int i;
memset(visit,false,sizeof(visit));
for(cnt=0,i=0;i<2*n;i++)
if(!visit[i])
dfs(i);
memset(id,0,sizeof(id));
memset(visit,false,sizeof(visit));
for(cnt=0,i=2*n-1;i>=0;i--)
if(!visit[order[i]])
{
cnt++;//这个一定要放前面来
rdfs(order[i]);
}
}
bool solvable()
{
for(int i=0;i<n;i++)
if(id[2*i]==id[2*i+1])
return false;
return true;
}void add(int x,int y)
{
adj[x].push_back(y);
radj[y].push_back(x);
}int b[600][600];
int bit[33];
int main()
{
int N;
bit[0]=1;
for(int i=1;i<31;i++)bit[i]=2*bit[i-1];
while(scanf("%d",&N)!=EOF)
{
n=N;
bool flag=true;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
{
scanf("%d",&b[i][j]);
if(i==j&&b[i][j]!=0)flag=false;
}
if(!flag)
{
printf("NO\n");
continue;
}
for(int i=0;i<N;i++)
{
if(!flag)break;
for(int j=i+1;j<N;j++)
if(b[i][j]!=b[j][i])
{
flag=false;
break;
}
}
if(!flag)
{
printf("NO\n");
continue;
}
for(int k=0;k<31;k++)
{
adj.assign(2*n,vector<int>());
radj.assign(2*n,vector<int>());
for(int i=0;i<N;i++)
for(int j=i+1;j<N;j++)
{
if(i%2==1&&j%2==1)
{
int t1=i;
int t2=j;
if(b[i][j]&bit[k])
{
add(2*t1,2*t2+1);
add(2*t2,2*t1+1);
}
else
{
add(2*t1+1,2*t1);
add(2*t2+1,2*t2);
}
}
else if(i%2==0&&j%2==0)
{
int t1=i;
int t2=j;
if(b[i][j]&bit[k])
{
add(2*t1,2*t1+1);
add(2*t2,2*t2+1);
}
else
{
add(2*t1+1,2*t2);
add(2*t2+1,2*t1);
}
}
else
{
int t1=i;
int t2=j;
if(b[i][j]&bit[k])
{
add(2*t1,2*t2+1);
add(2*t1+1,2*t2);
add(2*t2,2*t1+1);
add(2*t2+1,2*t1);
}
else
{
add(2*t1,2*t2);
add(2*t1+1,2*t2+1);
add(2*t2,2*t1);
add(2*t2+1,2*t1+1);
}}
}
korasaju();
if(!solvable())
{
flag=false;
break;
}
}
if(flag)printf("YES\n");
else printf("NO\n");
}
return 0;
}
C -The Little Girl who Picks Mushrooms
#include<stdio.h>
#include<string.h>
#define max(a , b) (a)>(b)?(a):(b)int main()
{
int a[5] , d[10][5]={0,1,2,3,4,0,1,3,2,4,0,1,4,2,3,0,2,3,1,4,0,2,4,1,3,0,3,4,1,2,1,2,3,0,4,1,2,4,0,3,1,3,4,0,2,2,3,4,0,1};
int n , M , i , j , temp ,flag;
while(scanf("%d",&n)!=EOF)
{
M=0;
memset(a , -1 , sizeof(a));
for(i=0 ; i<n ; i++)
scanf("%d",&a[i]);
for(i=0;i<10;i++)
{
temp=flag=0;
for(j=0 ; j<3 ; j++)
if(a[d[i][j]]==-1)
{
flag=1;
break;
}
else
temp += a[d[i][j]];
j=3;
if(flag)
{
temp=0;
for(j ; j<5 ; j++)
if(a[d[i][j]]==-1)
{
M=1024;
break;
}
else
{
temp += a[d[i][j]];
}
if(M==1024)
break;
while(temp>1024)
temp -= 1024;
M=max(M,temp);
}
else
{
if(temp%1024==0)
{
temp=0;
for(j ; j<5 ; j++)
if(a[d[i][j]]==-1)
{M=1024;
break;
}
else
temp += a[d[i][j]];
if(M==1024)
break;
while(temp>1024)
temp -= 1024;
M=max(M , temp);}
}}
printf("%d\n" , M);
}
return 0;
}
#include<stdio.h>//这个是转的
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
int a[6];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int sum=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
if(n>=0&&n<=3)
{
printf("1024\n");
continue;
}
int ans=0;
if(n==5)
{
for(int i=0;i<5;i++)
for(int j=i+1;j<5;j++)
for(int k=j+1;k<5;k++)
if((a[i]+a[j]+a[k])%1024==0)
{
int temp=sum-a[i]-a[j]-a[k];
while(temp>1024)temp-=1024;
if(temp>ans)ans=temp;
}
printf("%d\n",ans);
continue;
}if(n==4)
{
ans=0;
for(int i=0;i<4;i++)
for(int j=i+1;j<4;j++)
for(int k=j+1;k<4;k++)
if((a[i]+a[j]+a[k])%1024==0)
{
ans=1024;
}
if(ans>0)
{
printf("1024\n");
continue;
}
for(int i=0;i<4;i++)
for(int j=i+1;j<4;j++)
{
int temp=a[i]+a[j];
while(temp>1024)temp-=1024;
if(temp>ans)ans=temp;
}
printf("%d\n",ans);
continue;
}
}
return 0;
}

E -Conquer a New Region
  # include<cstdio>
# include<cstring>
# include<algorithm>
const int maxn=200001;
using namespace std;
struct Edge
{
int u,v,w;
}edge[maxn];
int f[maxn],num[maxn];
long long cost[maxn];
int find(int x)
{
/*if(f[u]==u) return u;
return f[u] = find(f[u]);*/
return x==f[x]?x:find(f[x]);
}
bool cmp(struct Edge a,struct Edge b)
{
return a.w > b.w;
}
int main()
{
int n,i;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<n;i++)
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
sort(edge+1,edge+n,cmp);
for(i=1;i<=n;i++)
f[i] = i, num[i]=1, cost[i]=0;
for(i=1;i<n;i++)
{
int x1=find(edge[i].u);
int x2=find(edge[i].v);
if(x1!=x2)
{
cost[x2] = max((long long)num[x1]*edge[i].w+cost[x2],(long long)num[x2]*edge[i].w+cost[x1]);
num[x2]+=num[x1];
f[x1]=x2;
}
}
printf("%lld\n",cost[find(1)]);
}
return 0;
}

H -Math Magic很水的DP,长春赛的时候竟然没有做出来。。。。。方向是写对了的,只是最后半个小时写的,很紧张。最后超时了。需要注意些细节,一些初始化才不会超时。预处理出LCM[1000][1000]来。dp[now][i][j]表示当前状态下,和为i,LCM为j的解的个数。递推K次就出答案了
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
using namespace std;
const int MOD=1000000007;
int dp[2][1010][1010];int num[1000];int gcd(int a,int b)
{
if(b==0)return a;
return gcd(b,a%b);
}
int lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
int LCM[1010][1010];
int main()
{
int n,m,k;
for(int i=1;i<=1000;i++)
for(int j=1;j<=1000;j++)
LCM[i][j]=lcm(i,j);while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
int cnt=0;
for(int i=1;i<=m;i++)
{
if(m%i==0)
num[cnt++]=i;
}
int now=0;
//memset(dp[now],0,sizeof(dp[now]));
for(int i=0;i<=n;i++)
for(int j=0;j<cnt;j++)
dp[now][i][num[j]]=0;
dp[now][0][1]=1;for(int t=1;t<=k;t++)
{
now^=1;
// memset(dp[now],0,sizeof(dp[now]));
for(int i=0;i<=n;i++)
for(int j=0;j<cnt;j++)
dp[now][i][num[j]]=0;
for(int i=t-1;i<=n;i++)
for(int j=0;j<cnt;j++)
{
if(dp[now^1][i][num[j]]==0)continue;
for(int p=0;p<cnt;p++)
{
int x=i+num[p];
//int y=lcm(num[j],num[p]);
int y=LCM[num[j]][num[p]];
if(x>n||m%y!=0)continue;
dp[now][x][y]+=dp[now^1][i][num[j]];
dp[now][x][y]%=MOD;
}
}
}
printf("%d\n",dp[now]
[m]);
}
return 0;
}
J -Split the Rectangle其实这题是不难的,注意是看懂题目意思。只要按照加入的边建立树。然后每次的查询就是求出这个点所在的叶子结点编号。然后求出这两个叶子结点的LCA,暴力求LCA即可。然后答案就是 n+1-(LCA所在结点下面的叶子结点个数)+1 很好的一道题。注意给的点是没有顺序的。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
using namespace std;
const int MAXN=2020;struct Node
{
int lson,rson,father;
int dep;//深度
int xl,yl,xr,yr;
void init(int de,int f)
{
lson=rson=0;
father=f;
dep=de;
}
void update(int a,int b,int c,int d)
{
xl=a;yl=b;xr=c;yr=d;
}
}node[MAXN];//结点
int tol;
int num[MAXN];//每个结点下的叶子结点个数int root;//根结点int find(int root,int x,int y)
{
int tmp=root,tt;
while(1)
{
if(node[tmp].lson==0)return tmp;
tt=node[tmp].lson;
if(x<=node[tt].xr&&x>=node[tt].xl&&y>=node[tt].yl&&y<=node[tt].yr)tmp=tt;
else tmp=node[tmp].rson;
}
}int get_num(int now)
{
num[now]=0;
if(node[now].lson==0)
{
return num[now]=1;
}
else
{
num[now]+=get_num(node[now].lson);
num[now]+=get_num(node[now].rson);
}
return num[now];
}int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int xl,yl,xr,yr;
int n,q;while(scanf("%d%d%d%d",&xl,&yl,&xr,&yr)!=EOF)
{
root=0;
node[root].init(0,-1);
node[root].update(xl,yl,xr,yr);
tol=1;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d%d",&xl,&yl,&xr,&yr);
if(xl>xr)swap(xl,xr);
if(yl>yr)swap(yl,yr);
int pos=find(root,(xl+xr)/2,(yl+yr)/2);
int dep=node[pos].dep;node[pos].lson=tol;
node[tol].init(dep+1,pos);
node[tol].update(node[pos].xl,node[pos].yl,xr,yr);
tol++;node[pos].rson=tol;
node[tol].init(dep+1,pos);
node[tol].update(xl,yl,node[pos].xr,node[pos].yr);
tol++;
}
get_num(root);
while(q--)
{
scanf("%d%d%d%d",&xl,&yl,&xr,&yr);
int tmp1=find(root,xl,yl);
int tmp2=find(root,xr,yr);while(tmp1!=tmp2)
{
if(node[tmp1].dep<node[tmp2].dep)tmp2=node[tmp2].father;
else if(node[tmp1].dep>node[tmp2].dep)tmp1=node[tmp1].father;
else
{
tmp1=node[tmp1].father;
tmp2=node[tmp2].father;
}
}
printf("%d\n",n+1-num[tmp1]+1);
}
}
return 0;
}
K -Yukari's Birthday
// File Name: eee.cpp
// Author: rudolf
// Created Time: 2013年04月17日 星期三 19时16分37秒#include<math.h>
#include<stdio.h>
#define LL long longLL Pow(int x ,int y)
{
int i;
LL sum=1;
for(i=0;i<y;i++ )
sum *= x ;
return sum ;
}int main()
{LL n,le,ri,k,mid,ans;
LL i , j,r;
while(scanf("%lld",&n)!= EOF)
{
r=1;
k=n-1;
for(i=2;i<=46;i++)
{le = 2 ;
ri = pow(n,1.0/i);while(le<=ri)
{
mid=(LL)(le+ri)/2;
ans = (mid-Pow(mid,i+1))/(1-mid);
if(ans==n|| ans==(n - 1))
{
if(r*k>i*mid)
{
r=i;
k=mid;
}
break;
}
else if(ans > n)
ri = mid - 1;
else
le = mid + 1;
}}
printf("%lld %lld\n",r,k);}
return 0;
}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息