“网宿科技杯”厦门大学第九届程序设计竞赛 现场决赛
“网宿科技杯”厦门大学第九届程序设计竞赛 现场决赛
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;
}