“网宿科技杯”厦门大学第九届程序设计竞赛 现场决赛

“网宿科技杯”厦门大学第九届程序设计竞赛 现场决赛

1342.篡改记忆抢劫事件

 

文吉利他们用stl库暴力过了,很让人YY,我作了点小优化居然超时了(stl也有效率高的时候,orz~~),后来卡过去了。

#include<stdio.h>

#include<string.h>

#include<math.h>

#include<stdlib.h>

int as[2006][1005],vis[2006];

int judge(int m,int x,int y)

{

    int i,k = 0;

    for(i = 0; i < m; ++ i) if(as[x][i] != as[y][i]){ k++; if(k > 2)break;}

    if(k == 2) return 1;

    vis[x] = 1;

    vis[y] = 1;

    return 0;

}

int main()

{

    int i,j,k,n,m;

    while(scanf("%d%d",&n,&m)==2)

    {

             memset(vis,0,sizeof(vis));

              for(i = 0; i < n; ++ i)for(j = 0; j < m; ++ j)scanf("%d",&as[i][j]);

                             //把i从0到n-1改成从n-1到n就过了

              for(i = n-1; i >= 0; -- i)if(!vis[i]){

                    for(j = 0; j < n; ++j) if(i != j){ if(!judge(m,i,j)) break; }

                    if(j==n)break;

              }

              printf("%d\n",i+1);

    }return 0;

}

 

1344.建食堂

 

思路:复杂模拟,做两次dfs;

先任选一叶子结点为树根,第一个dfs遍历一遍树,求出各子树的t1[x],2[x],ssum[x],sumk[x]。

第二个DFS再遍历一次树,求最优解

 

#include<stdio.h>

#include<iostream>

#include<string.h>

#include<algorithm>

#include<vector>

using namespace std;

long long ans,inf = 0xfffffff;

vector<long long>tree[10009];//原来的树形图,点之间的关连

vector<long long>cost[10009];//原来的树形图,点之间的距离

vector<long long>t1[10009];//t1[x]为x到各子树的距离(一个子树一个值,分开的)

vector<long long>t2[10009];// t2[x]为x的各子树的有多个点(一个子树一个值,分开的)

long long ssum[10009];//ssum[x]为x的各子树值之和

long long sumk[10009];//sumk[x]为x的各子树点之和

long long in[10009],vis[10009];

 

long long dfs(long long pre,long long x,long long sum,long long cnt,long long& ss)

{

       long long s = 0,ck = 0,sk = 0;

       for(long long i = 0; i < tree[x].size(); ++ i)if(tree[x][i]!=pre){

               sk = 0;

              long long k = dfs(x,tree[x][i],sum+cost[x][i]*cnt,cnt+1,sk);

               ck += k;

               s += sk;

               s += k * cost[x][i];

               t1[x].push_back(sk+k*cost[x][i]);

               t2[x].push_back(k);

       }

       ssum[x] = s;

       sumk[x] = ck;

       ss = s;

       return ck + 1;

}

 

 

void DFS(long long pre,long long x,long long sum,long long cnt)

{

       long long j =0;

       if(ssum[x]+sum<ans) ans = ssum[x] + sum;

//     printf("%lld %lld %lld %lld %lld\n",pre,x,ans,ssum[x],sum);

       for(long long i = 0; i < tree[x].size(); ++ i)if(tree[x][i]!=pre){

               long long k = sum+cost[x][i]*(cnt+sumk[x]-t2[x][j])+ssum[x]-t1[x][j];

               long long t = cnt+1+sumk[x]-t2[x][j++];

               DFS(x,tree[x][i],k,t);

       }

}

 

int main()

{

       long long u,v,w,n,i;

       while(scanf("%lld",&n)&&n)

       {

               for(i = 0; i < 10009; ++ i){ tree[i].clear(); cost[i].clear(); t1[i].clear(); t2[i].clear(); }

               memset(in,0,sizeof(in));

               memset(vis,0,sizeof(vis));

               memset(sumk,0,sizeof(sumk));

               memset(ssum,0,sizeof(ssum));

               for(long long i = 0; i < n - 1; ++ i)

               {

                      scanf("%lld %lld %lld",&u,&v,&w);

                      tree[u].push_back(v);

                      cost[u].push_back(w);

                      cost[v].push_back(w);

                      tree[v].push_back(u);

                      in[v]++;

                      in[u]++;

               }

               ans = inf * inf;

               long long s = 0;

               for(i = 1; i <= n; ++ i) if(in[i]==1){ dfs(-1,i,0,1,s); DFS(-1,i,0,1); break; }

               printf("%lld\n",ans);

       }return 0;

}

 

1343.灵异空间的逃亡

正解是:加边法建图+spfa

但是我不会加边法,用bfs水过的(代码略)

 

 

1345.机器的指示灯

#include<stdio.h>

#include<string.h>

char as[10000],bs[10000],cs[10000];

int main()

{

       int ans,i,j,k,t;

       scanf("%d",&t);

       while(t--)

       {

               scanf("%s %s",as,bs);

               ans = strlen(as);

               k = 1;

               for(i = 0; bs[i]; ++ i) if(bs[i]=='0') ++k;

               if(k<ans)ans = k; k = 1;

               for(i = 0; bs[i]; ++ i) if(bs[i]=='1') ++k;

               if(k<ans)ans = k; k = 0;

               for(i = 0; bs[i]; ++ i) if(bs[i]!=as[i]) ++k;

               if(k<ans)ans = k; k = 1;

               for(i = 0; as[i]; ++ i) if(as[i]==bs[i])++k;

               if(k<ans)ans = k;

               printf("%d\n",ans);

       }return 0;

}

posted on 2012-05-13 19:54  aigoruan  阅读(258)  评论(0)    收藏  举报

导航