A - Seats(模拟)
题意:给定字符串s,求i和i+2为#,i+1为.的个数
代码:
#include<bits/stdc++.h> using namespace std; int main(){ int n;cin>>n; string s;cin>>s; int ans=0; for(int i=0;i<n-2;i++){ if(s[i]=='#'&&s[i+1]=='.'&&s[i+2]=='#')ans++; } cout<<ans<<endl; }
B - Traveling Takahashi Problem(模拟)
题意:依次访问xi,yi然后返回原点,从a,b到c,d的代价为sqrt((a-c)²+(b-d)²)
分析:每次用cd记录上次的位置
代码:
#include<bits/stdc++.h> using namespace std; int main(){ int n;cin>>n; double ans=0;double a,b,c=0,d=0; for(int i=1;i<=n;i++){ cin>>a>>b; ans+=sqrt((c-a)*(c-a)+(d-b)*(d-b)); c=a,d=b; } ans+=sqrt(c*c+d*d); printf("%.20f\n",ans); return 0; }
C - Spiral Rotation(模拟)
题意:给定n×n的网格,一共n/2次操作,对i和n+1-i之间的所有整数对 x,y ,用单元格 (x,y) 的颜色替换单元格 (y,N+1−x)的颜色
分析:每个方格有4种替换,即旋转一周,计算每个方格需要几次替换也就是k
代码:
#include<bits/stdc++.h> using namespace std; int main(){ int n;cin>>n; char a[n+10][n+10]; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cin>>a[i][j]; } } char b[n+10][n+10]; int k; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ k=min(abs(n-i),abs(n-j))+1; k=min(k,min(i,j)); // if(k==0)k=1; // cout<<k<<endl; if(k%4==0)b[i][j]=a[i][j]; else if(k%4==1)b[i][j]=a[n+1-j][i]; else if(k%4==2)b[i][j]=a[n+1-i][n+1-j]; else if(k%4==3)b[i][j]=a[j][n+1-i]; } } //j=n+1-i //i=n+1-j for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cout<<b[i][j]; } cout<<endl; } return 0; }
D - ABA(枚举)
题意:给定字符串,找出三个字符的回文个数
分析:用mpc记录当前字符之前出现的个数,用mp记录之前每个点相加的值,特殊情况是当前面一个字符与当前字符相同时要对mp和mpc进行处理。
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+10; //int mp[N]; int main(){ string s;cin>>s; s='-'+s; map<char,ll>mpc,mp; ll ans=0; for(int i=1;i<s.size();i++){ char x=s[i]; if(s[i-1]!=x&&mpc[x]>=1){ ll a=i*mpc[x]-mp[x]-mpc[x]; ans+=a; } else if(s[i-1]==x&&mpc[x]>=1){ ll a=i*(mpc[x]-1)-(mp[x]-(i-1))-(mpc[x]-1); ans+=a; } mp[x]+=i; mpc[x]++; } cout<<ans<<endl; return 0; }
E - 3 Team Division(dp)
题意:有n个人分成三组,第i个人属于ai小组,强度为bi,一个团队的强度被定义为所有成员强度的总和。是否有可能让零个或更多个人交换团队,从而使所有团队的实力相等。求最少需要几个人换。
分析:用二维dp记录每次经过一个人所有的dp变化
代码:
#include <bits/stdc++.h> using namespace std; template<class T, class U> inline bool chmin(T& a, const U& b) { if (a > b) { a = b; return true; } return false; } int main() { int n; cin >> n; vector<int> a(n), b(n); for (int i = 0; i < n; i++) cin >> a[i] >> b[i]; int sum = accumulate(b.begin(), b.end(), 0); if (sum % 3 != 0) { cout << "-1\n"; return 0; } int A = 501;//总和<1500 每个队伍最大范围不超过500 int inf = 1000000000; vector<vector<int>> dp(A, vector<int>(A, inf)); dp[0][0] = 0; for (int i = 0; i < n; i++) { vector<vector<int>> ep(A, vector<int>(A, inf));//每次重新定义,作为存储中间过程的容器 int e = b[i]; for (int j = 0; j < A; j++) {//dp[j][k]表示 第i个信息对应的队1和队2的值 for (int k = 0; k < A; k++) { if (a[i] == 1) {//队1 //若加上改点不超出数据范围 更新ep为当前数值对应的最小步骤 if (j + e < A) chmin(ep[j + e][k], dp[j][k]); if (k + e < A) chmin(ep[j][k + e], dp[j][k] + 1); chmin(ep[j][k], dp[j][k] + 1);//分配给队3操作数+1 } else if (a[i] == 2) {//队2 if (j + e < A) chmin(ep[j + e][k], dp[j][k] + 1); if (k + e < A) chmin(ep[j][k + e], dp[j][k]); chmin(ep[j][k], dp[j][k] + 1); } else {//队3 if (j + e < A) chmin(ep[j + e][k], dp[j][k] + 1); if (k + e < A) chmin(ep[j][k + e], dp[j][k] + 1); chmin(ep[j][k], dp[j][k]); } } } dp = move(ep);//更新dp为当前b[i]处理后的 } int res = dp[sum / 3][sum / 3];//若该情况重新赋值,说明存在 则输出 cout << (res == inf ? -1 : res) << '\n'; return 0; }
F - Road Blocked(最短路)
题意:ai城市与bi城市相连,长度为ci。给定q个查询,1 i:道路i关闭,2 x y打印x道y的最短距离,如果没有就输出-1.
分析:先得到删除完边的答案,然后倒叙每次加一条边输出最短路
代码:
#include <bits/stdc++.h> using namespace std; #define int long long const int N = 1e6 + 5, M = 300 + 10; const long long inf = 1e18; int n, m, q; struct node { int u, v, w; } e[N]; pair<int, int> qu[N]; bool vis[N]; int f[M][M]; void Solve() { cin >> n >> m >> q; for(int i=1;i<=m;i++) { int u, v, w; cin >> u >> v >> w; e[i] = {u, v, w}; } for(int i=1;i<=q;i++) { int opt, x, y; cin >> opt; if(opt == 1) cin >> x, qu[i] = {x, inf}, vis[x] = 1; else cin >> x >> y, qu[i] = {x, y}; } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i != j) f[i][j] = inf; } } for(int i=1;i<=m;i++){ if(!vis[i]) f[e[i].u][e[i].v] = f[e[i].v][e[i].u] = e[i].w; } //得到删除边后的答案 for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ f[i][j] = min(f[i][j], f[i][k] + f[k][j]); } } } vector<int> ans; for(int i= q;i>= 1;i--) {//倒序恢复 if(qu[i].second == inf) {//如果为删除边操作 判断是否能成为最短路的一部分 int u = e[qu[i].first].u, v = e[qu[i].first].v;//得到边的两端uv f[u][v] = f[v][u] = min(f[u][v], e[qu[i].first].w);//为边赋值 for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){//该边有作用的两种可能 f[i][j] = min(f[i][j], min(f[i][u] + f[u][v] + f[v][j], f[i][v] + f[v][u] + f[u][j])); } } } else{ ans.emplace_back((f[qu[i].first][qu[i].second] >= inf ? -1 : f[qu[i].first][qu[i].second])); } } reverse(ans.begin(), ans.end()); for(auto p : ans) cout << p << '\n'; } signed main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); Solve(); return 0; }