比賽總結
第一次AK掉div 2,非常開心,罰時也還好。
比賽中的提交記錄
在正式和非正式選手中排名179名(共6932人)
在正式選手裏排名27名(共2826人)
A. Toy Cars
題目鏈接
http://codeforces.com/contest/545/problem/A
題目大意
給出每個車
思路
水題,就不多說了
代碼
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <vector>
#define MAXN 110
using namespace std;
int mat[MAXN][MAXN],n;
int sol[MAXN],top=0;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&mat[i][j]);
for(int i=1;i<=n;i++)
{
bool flag=true;
for(int j=1;j<=n;j++)
if(mat[i][j]==1||mat[i][j]==3)
{
flag=false;
break;
}
if(flag) sol[++top]=i;
}
printf("%d\n",top);
if(!top) return 0;
for(int i=1;i<=top;i++)
printf("%d ",sol[i]);
printf("\n");
return 0;
}
B. Equidistant String
題目鏈接
http://codeforces.com/contest/545/problem/B
題目大意
定義兩個串
要你構造一個串
思路
水題,首先看
代碼
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <vector>
#define MAXN 110000
using namespace std;
char A[MAXN],B[MAXN];
int n;
int main()
{
scanf("%s",A+1);
scanf("%s",B+1);
n=strlen(A+1);
int tot=0;
for(int i=1;i<=n;i++)
if(A[i]!=B[i])
tot++;
if(tot&1)
{
printf("impossible\n");
return 0;
}
tot/=2;
for(int i=1,t=1;i<=n;i++)
{
if(A[i]==B[i]) printf("%c",A[i]);
else if(t<=tot) {printf("%c",A[i]); t++;}
else printf("%c",B[i]);
}
printf("\n");
return 0;
}
C. Woodcutters
題目鏈接
http://codeforces.com/contest/545/problem/C
題目大意
一共有
思路
第
然後剩餘要做的事就是各種特判了。
代碼
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <vector>
#define MAXN 110000
using namespace std;
typedef long long int LL;
int n;
LL h[MAXN],x[MAXN];
int f[MAXN][3];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%I64d%I64d",&x[i],&h[i]);
f[1][0]=f[1][1]=f[1][2]=1;
for(int i=2;i<=n;i++)
{
//往左倒
if(x[i]-h[i]>x[i-1]+h[i-1]) f[i][0]=max(f[i][0],f[i-1][2]+1);
if(x[i]-h[i]>x[i-1])
{
f[i][0]=max(f[i][0],f[i-1][1]);
f[i][0]=max(f[i][0],f[i-1][0]+1);
}
//拔出
if(x[i]>x[i-1]) f[i][1]=max(f[i][1],f[i-1][1]);
if(x[i]>x[i-1]+h[i-1]) f[i][1]=max(f[i][1],f[i-1][2]+1);
if(x[i]>x[i-1]) f[i][1]=max(f[i][1],f[i-1][0]+1);
//往右倒
if(x[i]>x[i-1]+h[i-1]) f[i][2]=max(f[i][2],f[i-1][2]+1);
if(x[i]>x[i-1])
{
f[i][2]=max(f[i][2],f[i-1][1]);
f[i][2]=max(f[i][2],f[i-1][0]+1);
}
}
printf("%d\n",max(max(f[n][0],f[n][1]),f[n][2]));
return 0;
}
D. Queue
題目鏈接
http://codeforces.com/contest/545/problem/D
題目大意
給你
思路
非常水的DP,顯然要讓
代碼
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#define MAXN 110000
using namespace std;
typedef long long int LL;
//priority_queue<LL>heap;
int n;
LL t[MAXN];
int main()
{
int ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%I64d",&t[i]);
sort(t+1,t+n+1);
//reverse(t+1,t+n+1);
LL nowt=0;
for(int i=1;i<=n;i++)
{
if(t[i]<nowt) continue;
ans++;
nowt+=t[i];
}
printf("%d\n",ans);
return 0;
}
E. Paths and Trees
題目鏈接
http://codeforces.com/contest/545/problem/E
題目大意
給你一個無向圖,要你找出一個生成樹,使得生成樹裏
思路
首先,kruscal的做法顯然是錯誤的,具體可以看第二個樣例。
我們不妨用單源最短路算法先求出一個從
不妨改進堆優化Dijsktra。堆中不僅記錄點和點到S的距離,還要加上一個標記:這個點是從哪條邊走過來的。這樣的話,假如在做dijsktra時,我們同時看到有兩個點到
代碼
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#define MAXN 610000
using namespace std;
typedef long long int LL;
struct edge
{
int u,v,id,next;
LL w;
}edges[MAXN];
int n,m;
int head[MAXN],nCount=1;
void AddEdge(int U,int V,LL W,int ID)
{
edges[++nCount].u=U;
edges[nCount].v=V;
edges[nCount].w=W;
edges[nCount].id=ID;
edges[nCount].next=head[U];
head[U]=nCount;
}
LL dist[MAXN];
bool vis[MAXN];
bool used[MAXN];
int pre[MAXN];
struct Info
{
int u;
LL w;
LL dis;
Info(int _u,LL _d,LL _w):u(_u),dis(_d),w(_w){}
};
bool operator<(Info a,Info b)
{
if(a.dis==b.dis) return a.w<b.w;
return a.dis<b.dis;
}
bool operator>(Info a,Info b)
{
if(a.dis==b.dis) return a.w>b.w;
return a.dis>b.dis;
}
priority_queue<Info,vector<Info>,greater<Info> >heap;
void heapdij(int S)
{
memset(dist,0x3f,sizeof(dist));
dist[S]=0;
heap.push(Info(S,0,0));
while(!heap.empty())
{
Info now=heap.top();
heap.pop();
int u=now.u;
if(vis[u]) continue;
vis[u]=true;
for(int p=head[u];p!=-1;p=edges[p].next)
{
int v=edges[p].v;
if(dist[u]+edges[p].w<=dist[v])
{
if(pre[v]!=-1) used[pre[v]]=false;
pre[v]=edges[p].id;
used[edges[p].id]=true;
dist[v]=dist[u]+edges[p].w;
heap.push(Info(v,dist[v],edges[p].w));
}
}
}
}
int main()
{
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v;
LL w;
scanf("%d%d%I64d",&u,&v,&w);
AddEdge(u,v,w,i);
AddEdge(v,u,w,i);
}
int S;
scanf("%d",&S);
heapdij(S);
LL tot=0;
for(int i=1;i<=m;i++)
if(used[i]) tot+=(LL)edges[i*2].w;
printf("%I64d\n",tot);
for(int i=1;i<=m;i++)
if(used[i])
printf("%d ",i);
printf("\n");
return 0;
}