2020hdu多校第四场比赛及补题
1005 Equal Sentences
队友过的一题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #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
队友过的一题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #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
???题,我们队三人还真一直在算,直到我偷听到答案。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #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点,然后建图,拆点建图细节比较多,我改了挺久
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | #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用的是软白的板子,用不来,在那套板子套了挺久还是没套好,然后又去检查建图,最后只好用我好久没用的二分图最大匹配模板,重新写一遍,过了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #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; } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步