SDUT 2022 Summer Individual Contest - 2 (补题)
题目链接:
概述:将A串转化为B串,给定了转化各个字符的花费,求解转化最小代价或输出-1
分析:可以对ASCII码进行Floyd运算 或 对于每个点跑一遍堆优化Dijkstra
Floyd(copy滨神):
#include <iostream> #include <algorithm> #include <cstring> #include <string> using namespace std; #define endl '\n' #define _ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); const int N=1e6+10; const int mod=1e9+7; int g[200][200]; void floyed() { for (int k=1;k<=130;k++) for (int i=1;i<=130;i++) for (int j=1;j<=130;j++) g[i][j]=min(g[i][j],g[i][k]+g[k][j]); } int main () { _ string s1,s2; cin>>s1>>s2; int n; cin>>n; for (int i=0;i<=140;i++) { for (int j=0;j<=140;j++) { if(i==j) g[i][j]=0; else g[i][j]=0x3f3f3f3f; } } while (n--) { char d,e; int c; cin>>d>>e>>c; int a=(int)d; int b=(int)e; g[a][b]=min(g[a][b],c); } floyed(); int ans=0; bool flag=1; for (int i=0;s1[i];i++) { int a=(int)s1[i];int b=(int)s2[i]; if (g[a][b]>0x3f3f3f3f/2) { flag=0; break; } ans+=g[a][b]; } if (flag) cout<<ans<<endl; else cout<<-1<<endl; }
Dijkstra:
#include <bits/stdc++.h> #define endl '\n' #define x first #define y second #define PI acos(-1) #define int long long #define SugarT ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); using namespace std; const int N=1e5+10; const int INF=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const double eps = 1e-6; typedef pair<int,int> PII; int n,m,t,sum; int h[N],e[N],ne[N],w[N],idx; int dist[N]; string a,b; bool st[N]; bool flag; map<char,int> mp; int v[130][130]; int cnt=1; void add(int a,int b,int c) { e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++; } void Dijkstra(int s) { memset(dist,0x3f,sizeof dist); memset(st,false,sizeof st); dist[s]=0; priority_queue<PII,vector<PII>,greater<PII>> q; q.push({0,s}); while(q.size()) { auto t=q.top(); q.pop(); int dis=t.x,ver=t.y; if(st[ver])continue; st[ver]=true; for(int i=h[ver];i!=-1;i=ne[i]) { auto j=e[i]; if(dist[j]>dist[ver]+w[i]) { dist[j]=dist[ver]+w[i]; q.push({dist[j],j}); } } } for(int i=1;i<cnt;i++) if(dist[i]>INF/2 && v[s][i])flag=true; else sum+=v[s][i]*dist[i]; } void solve() { memset(h,-1,sizeof h); cin >> a >> b >> t; for(int i=0;i<a.size();i++)//离散化防止重复 { if(!mp[a[i]])mp[a[i]]=cnt++; if(!mp[b[i]])mp[b[i]]=cnt++; } while(t--) { char aa,bb; int c; cin >> aa >> bb >> c; if(!mp[aa])mp[aa]=cnt++; if(!mp[bb])mp[bb]=cnt++; add(mp[aa],mp[bb],c); } for(int i=0;i<a.size();i++) v[mp[a[i]]][mp[b[i]]]++; for(int i=1;i<cnt;i++)//以每一个点为起点进行Dijkstra找到每个点对于它的最短路 Dijkstra(i); if(flag) cout << "-1" << endl; else cout << sum << endl; } signed main() { SugarT int T=1; //cin >> T; while(T--) solve(); return 0; }
题目链接:
概述:里面所有点的集合找到所有的{a,b},c在线段ab上并且c也是点
分析:将三角形化为直角三角形在一条直线仍然满足,两两枚举所有点的位置进行运算即可
#include <bits/stdc++.h> #define endl '\n' #define x first #define y second #define PI acos(-1) #define int long long #define SugarT ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); using namespace std; const int N=1e5+10; const int mod=1e9+7; const double eps = 1e-6; int q[60]; struct node { int a; int b; }s[N]; void solve() { int n; int ans=0; cin >> n; for(int i=1;i<60;i++)q[i]=q[i-1]+i; int cnt=1; for(int i=0;i<=n;i++) for(int j=n-i;j>=0;j--) s[cnt].a=i,s[cnt].b=j,++cnt; //for(int i=1;i<cnt;i++)cout << s[i].a << " " << s[i].b << endl; for(int i=1;i<cnt;i++) for(int j=i+1;j<cnt;j++) { if(__gcd(abs(s[i].a-s[j].a),abs(s[i].b-s[j].b))>1) { ans++; //cout << s[i].a << " " << s[i].b << " " << s[j].a << " " << s[j].b << " " << __gcd(abs(s[i].a-s[j].a),abs(s[i].b-s[j].b)) << endl; } } cout << ans << endl; } signed main() { SugarT int T=1; //cin >> T; while(T--) solve(); return 0; }
(今天才知道__gcd(0,x)=x)(bushi)
题目链接:
概述:每个人存在理发时间x与逃跑的概率y,求得最短的平均等待时间
分析:贪心求得每个人的个人花费时间期望值按照升序排序是期望最短时间的顺序,推到计算式可得:
第i个人的等待时间=(第i-1的等待时间+第i个人需要花费的时间)*第i个人不逃跑的概率+第i-1的等待时间*第i个人逃跑的概率
#include <bits/stdc++.h> #define endl '\n' #define PI acos(-1) #define int long long #define SugarT ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); using namespace std; const int N=5e5+10; const int INF=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const double eps = 1e-6; struct node { int x; double y; double ave; }q[N]; double ans[N]; bool cmp(node a,node b)//每个人的个人花费时间期望值按照升序排序 { return a.x*1.0*a.y<b.x*1.0*b.y; } void solve() { int n; cin >> n; for(int i=1;i<=n;i++)cin >> q[i].x >> q[i].y; sort(q+1,q+n+1,cmp); ans[0]=0; double sum=0; for(int i=1;i<=n;i++) { ans[i]=(ans[i-1]+q[i].x)*q[i].y+ans[i-1]*(1.0-q[i].y);//第i个人的等待时间=(第i-1的等待时间+第i个人需要花费的时间)*第i个人不逃跑的概率+第i-1的等待时间*第i个人逃跑的概率 sum+=ans[i]; } printf("%.9lf",1.0*sum/(n*1.0)); } signed main() { SugarT int T=1; //cin >> T; while(T--) solve(); return 0; }