1005 Equal Sentences
队友过的一题
#include <bits/stdc++.h> using namespace std; #define int long long const int MAXN = 1e5 + 7; const int MOD = 1e9 + 7; int T; int n; string str; string tmp, word; int cnt; int dp[MAXN][2]; int vis[MAXN]; int ans; int32_t main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> T; while (T--) { memset(vis, 0, sizeof(vis)); cnt = 0; ans = 0; word = ""; cin >> n; for (int i = 1; i <= n; ++i) { cin >> str; if (str != word) { cnt++; word = str; } vis[i] = cnt; } dp[0][0] = dp[0][1] = 0; dp[1][0] = 1; dp[1][1] = 0; for (int i = 2; i <= n; ++i) { if (vis[i] != vis[i - 1]) { dp[i][0] = dp[i - 1][0] + dp[i - 1][1] % MOD; dp[i][1] = dp[i - 1][0] % MOD; } else { dp[i][0] = dp[i - 1][0] + dp[i - 1][1] % MOD; dp[i][1] = 0 % MOD; } } ans = dp[n][0] + dp[n][1]; ans %= MOD; cout << ans << endl; } return 0; }
1002 Blow up the Enemy
队友过的一题
#include <iostream> #include <cstring> #include <cstdio> using namespace std; int data[1002]; int main(void){ int t; cin >> t; int n; while(t--){ scanf("%d", &n); int ai,di; int minn=999999999; for(int i=1;i<=n;i++){ scanf("%d %d", &ai, &di); if((100%ai)==0){ data[i]= di*(100/ai-1); }else{ data[i] = di*(100/ai); } if(minn > data[i]){ minn = data[i]; } } int ans = 0; for(int i=1;i<=n;i++){ if(minn < data[i]){ ans += 10; }else if(minn == data[i]){ ans += 5; }else{ ans += 0; } } double res = (double)ans/(double)n/10.0; cout << res << endl; } return 0; }
1011 Kindergarten Physics
???题,我们队三人还真一直在算,直到我偷听到答案。。。
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; const double res = 1e-10; int main() { int T,a,b,d; double t; cin>>T; while(T--){ cin>>a>>b>>t>>d; t-=res; printf("%.10lf\n",t); } return 0; }
1004 Deliver the Cake
n个点,m条边求最短路,
点有3个状态,L,R,M
L点到R点或R点到L点要额外增加 x 的距离,M点可当成L点或当成R点,M点不能同时当成L点和R点
看起来挺简单的,但比赛时没做出来,一直T
我乱魔改dijkstra,用了自己不会的语法
还是拆点好,直接把M点拆成一个L点和一个R点,然后建图,拆点建图细节比较多,我改了挺久
#include<iostream> #include<algorithm> #include<queue> #include<cstdio> #include<vector> using namespace std; const int MAXN = 2e5+7; const long long INF = 1e18+7; template<class T>inline void read(T& res) { char c; T flag = 1; while ((c = getchar()) < '0' || c > '9')if (c == '-')flag = -1; res = c - '0'; while ((c = getchar()) >= '0' && c <= '9')res = res * 10 + c - '0'; res *= flag; } struct EDGE{ int to,next; long long d; }edge[MAXN*8]; int head[MAXN],tot; long long n,m,s,t,x; char shou[MAXN]; long long dis[MAXN]; void add(int u,int v,long long w){ ++tot; edge[tot].to = v; edge[tot].d = w; edge[tot].next = head[u]; head[u] = tot; } void dijkstra(int st) { priority_queue< pair<long long,int> , vector<pair<long long,int> >, greater<pair<long long,int> > >que; dis[st] = 0; que.push({0,st}); while(!que.empty()){ int node = que.top().second; long long dt = que.top().first; if(dis[node] < dt){ que.pop(); continue; } que.pop(); for(int i = head[node];i;i = edge[i].next ){ int po = edge[i].to; long long lo = edge[i].d; if(dis[po] > dis[node] + lo){ dis[po] = dis[node] + lo; que.push({dis[po],po}); } } } return; } int main() { //freopen("D.in","r",stdin); int T; int u,v; long long d; cin>>T; while(T--){ tot = 0; scanf("%lld%lld%lld%lld%lld",&n,&m,&s,&t,&x); scanf("%s",shou + 1); for(int i = 1;i <= n; i++){ head[i] = head[i+n] = 0; dis[i] = dis[i+n] = INF; } for(int i = 1;i <= m; i++ ){ read(u);read(v);read(d); if(shou[u] == 'R') u += n; if(shou[v] == 'R' ) v += n; if(u <= n && v <= n) { add(u,v,d); add(v,u,d); } else if(u>n&&v>n){ add(u,v,d); add(v,u,d); } else { add(u,v,d+x); add(v,u,d+x); } if(u<=n&&v<=n&&shou[u]=='M'&&shou[v]=='M'){ add(u,v+n,d+x); add(v+n,u,d+x); add(u+n,v,d+x); add(v,u+n,d+x); add(u+n,v+n,d); add(v+n,u+n,d); } else if (u<=n&&shou[u] == 'M'){ if(v<=n){ add(u+n,v,d+x); add(v,u+n,d+x); } else{ add(u+n,v,d); add(v,u+n,d); } } else if(v<=n&&shou[v] == 'M'){ if(u<=n){ add(u,v+n,d+x); add(v+n,u,d+x); } else{ add(u,v+n,d); add(v+n,u,d); } } } long long ans; if(shou[s]=='L'){ dijkstra(s); ans = min(dis[t],dis[t+n]); } else if(shou[s]=='R'){ dijkstra(s+n); ans = min(dis[t],dis[t+n]); } else{ dijkstra(s); ans = min(dis[t],dis[t+n]); for(int i = 1;i<=n;i++){ dis[i] = dis[i+n] = INF; } dijkstra(s+n); ans = min(ans,min(dis[t],dis[t+n])); } printf("%lld\n",ans); } return 0; }
1007 Go Running
补题
看了下队友的代码,队友的代码比较神奇,有我没见过的语法,变量名又是fuck,又是shit的。。。
其实是挺简单的一题,我一看,就想到这是一个二分图题,可惜我比赛时没看这题(一直在搞1004qAq)
题目意思可以转化为给n组 t 和 x,每组t,x表示 t-x或t+x的位置上有人,问最少有多少人
把每个t-x点放到左边,每个t+x点放到右边,每组的t-x点连向对应的t+x点,发现就是个二分图最小点覆盖问题,最小点覆盖就是二分图最大匹配(我当时忘记了二分图最小点覆盖是什么,但直觉上感觉这就是个二分图最大匹配)
虽然一下就想到二分图,但我还是补了挺久
我想用网络流来做二分图最大匹配,而这题数据比较大,要用dinic,而我只会EK,不会dinic,我dinic用的是软白的板子,用不来,在那套板子套了挺久还是没套好,然后又去检查建图,最后只好用我好久没用的二分图最大匹配模板,重新写一遍,过了。
#include<iostream> #include<algorithm> #include<cstdio> #include<vector> #include<map> #include<queue> using namespace std; const int MAXN = 1e5+7; vector<int> graph[MAXN]; int n; int pei[MAXN],cc[MAXN]; bool eft(int st, int cur){ if(cc[st]==cur) return false; cc[st] = cur; for(int i = 0;i<graph[st].size();i++){ int po = graph[st][i]; if(pei[po] == st) continue; if(pei[po] == -1||eft(pei[po],cur)){ pei[po] = st; return true; } } return false; } int main() { //freopen("G.in","r",stdin); int T; cin>>T; int t,x; while(T--){ cin >> n; map<long long,int>ant1,ant2; int cnt1 = 0,cnt2 = 0; for(int i = 1;i <= n;i++){ scanf("%d%d",&t,&x); if(!ant1[x-t]) ant1[x-t] = ++cnt1; if(!ant2[x+t]) ant2[x+t] = ++cnt2; graph[ant1[x-t]].push_back(ant2[x+t]); } for(int i = 1;i <= cnt2;i++) pei[i] = -1; for(int i = 1;i <= cnt1;i++) cc[i] = -1; int ans = 0; for(int i = 1;i <= cnt1;i++) if(eft(i,i)) ans++; cout<<ans<<endl; for(int i = 1;i <= cnt1;i++) graph[i].clear(); } return 0; }