2020 Multi-University Training Contest 3 解題報告
阿新 • • 發佈:2020-07-29
1004
計算取模後的字首和,並且存到map裡,然後每次在map裡查詢是否有相同的數,有則答案加一,清空字首和和map,沒有則繼續往後找。不過要提前把是k的倍數加到答案裡,上面遇到0直接結束,清空map,查詢下一段。
#include <bits/stdc++.h> using namespace std; #define ll long long ll input(){ ll x=0,f=0;char ch=getchar(); while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return f? -x:x; } const int N=2e5+7; ll n,p; ll a[N]; map <ll,int> mp; int main(){ int T=input(); while(T--){ n=input(),p=input(); ll Ans=0; for(int i=1;i<=n;i++){ a[i]=input()%p; if(!a[i]) Ans++; } ll sum=0; for(int i=1;i<=n;i++){ if(a[i]==0){ mp.clear();sum=0; continue; } sum=(sum+a[i])%p; if(sum==0){Ans++;sum=0;mp.clear();} else if(mp[sum]>=1){Ans++;sum=0;mp.clear();} else mp[sum]++; } printf("%lld\n",Ans); } }
1009
溫暖的簽到。首先用棧匹配')'的括號,優先匹配靠前的'*',再梅開二度用棧匹配'(',優先匹配靠後'*',然後其它的‘*’都是空的。
#include <bits/stdc++.h> using namespace std; #define ll long long ll input(){ ll x=0,f=0;char ch=getchar(); while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return f? -x:x; } const int N=3e5+7; char s[N]; vector <int> star; stack <int> st1,st2; int main(){ int T=input(); while(T--){ while(!st1.empty()) st1.pop(); while(!st2.empty()) st2.pop(); scanf("%s",s+1); int len=strlen(s+1); star.clear(); for(int i=1;i<=len;i++){ if(s[i]=='*') star.push_back(i); } for(int i=len;i>=1;i--){ if(s[i]==')') st2.push(i); if(s[i]=='('&&!st2.empty()) st2.pop(); } // while(!st2.empty()) printf("%d\n",st2.top()),st2.pop(); int flag=0; for(int j=0;j<star.size();j++){ if(st2.empty()) break; if(st2.top()<star[j]) {flag=1;break;} s[star[j]]='(';st2.pop(); } if(!st2.empty()||flag==1){printf("No solution!\n");continue;} star.clear(); for(int i=len;i>=1;i--){ if(s[i]=='*') star.push_back(i); } for(int i=1;i<=len;i++){ if(s[i]=='(') st1.push(i); if(s[i]==')'&&!st1.empty()) st1.pop(); } // while(!st1.empty()) printf("%d\n",st1.top()),st1.pop(); flag=0; for(int j=0;j<star.size();j++){ if(st1.empty()) break; if(st1.top()>star[j]) {flag=1;break;} s[star[j]]=')';st1.pop(); } if(!st1.empty()||flag==1){printf("No solution!\n");continue;} for(int i=1;i<=len;i++){ if(s[i]=='*') continue; else printf("%c",s[i]); }printf("\n"); } }
1007
非傳統結論題。因為邊權隨機,所有最短路最長為3,直接dfs列舉最短路上邊,問題轉化為去掉\(k-1\)條邊的答案。
#include <bits/stdc++.h> using namespace std; #define ll long long ll input(){ ll x=0,f=0;char ch=getchar(); while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return f? -x:x; } const ll N = 2507; const ll INF = 0x3f3f3f3f3f3f3f; ll mp[N][N],vis[N*N],dis[N*N],head[N*N],path[10][N]; ll n,k; ll Ans=0; void spfa(int fg,int dep){ for(int i=0;i<=n;i++){ vis[i] = 0;dis[i] = INF; } queue <ll> q; q.push(1);dis[1] = 0; while(!q.empty()){ ll x = q.front();q.pop();vis[x] = 0; for(int i=1;i<=n;i++) if(mp[x][i]!=INF&&dis[i]>dis[x]+mp[x][i]){ dis[i] = dis[x]+mp[x][i]; if(fg==0) path[dep][i] = x; if(vis[i]==0){ vis[i] = 1; q.push(i); } } } } void dfs(int dep){ if(dep==0){spfa(1,dep); Ans=max(Ans,dis[n]); return;} spfa(0,dep); for(int i=n;path[dep][i]!=0;i=path[dep][i]){ ll tp = mp[path[dep][i]][i]; mp[path[dep][i]][i] = mp[i][path[dep][i]] = INF; dfs(dep-1); mp[path[dep][i]][i] = mp[i][path[dep][i]] = tp; } } void Solve(){ n=input(),k=input(); for(int i=0;i<=n;i++){ for(int j=0;j<=n;j++) mp[i][j] = INF; } for(int i=1;i<=(n*(n-1))/2;i++){ ll x=input(),y=input(),z=input(); mp[x][y] = mp[y][x] = z; } Ans=0; dfs(k); printf("%lld\n",Ans); } int main(){ int T=input(); while(T--) Solve(); }