第二届成都信息工程大学团体程序设计天梯赛
L1-7字符操作
题解:
遇到需要交换前后两段的选择时,如果直接把全部元素进行交换会超时,事实上不需要进行交换,只需要记录交换的次数,可以设立一个标志变量flag = 1,
变换奇数次flag为-1,交换偶数次flag为1,然后在进行交换单个字符时去想象两个字符在现有字符串中的相应关系进行交换即可。在所有查询结束后,再根据情况进行整体交换。查询次数为T,时间复杂度为\(O(T)\)。
code
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define pb push_back
#define ff first
#define se second
#define pii pair<ll,ll>
const int maxn = 5e5+5;
char ans[maxn];
char s[maxn];
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,k,flag = 1;
string s;
cin >> n >> s >> k;
s = " "+s;
while(k--){
int t,a,b;
cin >> t >> a >> b;
if(t==1){
if(a > n && b > n){
if(flag == -1)
swap(s[a-n], s[b-n]);
else
swap(s[a], s[b]);
}else if(a <= n && b <= n){
if(flag == -1)
swap(s[a+n], s[b+n]);
else
swap(s[a], s[b]);
}else{
if(flag == -1 && a < b)
swap(s[a+n], s[b-n]);
else if(flag == -1 && a > b )
swap(s[a-n], s[b+n]);
else
swap(s[a], s[b]);
}
}
else{
flag*=-1;
}
}
if(flag == -1){
for(int i = 1; i <= n;++i)
ans[i] = s[n+i];
for(int i = n+1; i<=2*n; ++i)
ans[i] = s[i-n];
}else{
for(int i = 1;i <= 2*n; ++i)
ans[i] = s[i];
}
for(int i = 1; i <= 2*n; ++i)
cout << ans[i];
return 0;
}
L2-3简单的数数
题解:
动态规划问题,\(dp[i][j]\) 表示前i位数合并成数字j所用的方案数,动态转移方程:
\[dp[i][(j+a[i])\%10] += dp[i-1][j]
\]
\[dp[i][(j*a[i])\%10] += dp[i-1][j]
\]
code
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define pb push_back
#define ff first
#define se second
#define pii pair<ll,ll>
const int maxn = 1e5+5;
const ll mod = 998244353;
int a[maxn];
ll dp[maxn][15];
int n;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for(int i = 1; i <= n; ++i)
cin >> a[i];
dp[1][a[1]] = 1;
for(int i = 2;i <= n; ++i){
for(int j = 0;j < 10; ++j){
int k1 = (j + a[i]) % 10;
int k2 = (j * a[i]) % 10;
dp[i][k1]=(dp[i][k1]+dp[i-1][j])%mod;
dp[i][k2]=(dp[i][k2] + dp[i-1][j])%mod;
}
}
dp[1][a[1]] = 1;
for(int i = 0; i < 10 ;++i)
cout << dp[n][i] << '\n';
return 0;
}
L2-4 回家日
题解:
先根据解封的时间对城市进行排序,每一次取出解封时间最早的城市,如果该城市存在一条和学校连通的的路,则记录下解封时间,并且搜索所有和该城市在一个连通块中的城市,并且更新所有在连通块中城市到学校的距离,由于只需要判断是否连通,则只要某座城市和学校连通,则直接记录距离为1即可,如果找到解封时间早于当前时间的城市,则记录下该城市的解封时间,该过程可用dfs来实现。
code
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define pb push_back
#define ff first
#define se second
#define pii pair<ll,ll>
const int maxn = 1e5+5;
const int inf = 0x3f3f3f3f;
struct edge{
int to;
int w;
edge(int a, ll b){to = a; w = b;};
};
vector<edge>e[maxn];
int n,m,k;
int A[maxn],Day[maxn],done[maxn],dist[maxn];
int ans[maxn];
struct node{
int id;
int day;
node(int a,int b){id = a; day = b;};
bool operator < (const node &a)const
{return day > a.day;}
};
void dfs(int to, int day){
for(int i = 0;i < e[to].size();++i){
edge tmp = e[to][i];
if(done[tmp.to])
continue;
if(tmp.w < inf){
dist[tmp.to] = 1;
if(Day[tmp.to] < day){
ans[tmp.to] = day;
done[tmp.to] = 1;
dfs(tmp.to,day);
}
}
}
}
void solve(){
priority_queue<node>q;
for(int i = 1; i <= n; ++i)
Day[A[i]] = i;
dist[k] = 1;
for(int i = 1; i <= n; ++i)
q.push(node(A[i],i));
while(!q.empty()){
node u = q.top();
q.pop();
if(done[u.id])
continue;
if(dist[u.id] < inf){
ans[u.id] = u.day;
done[u.id] = 1;
dfs(u.id,u.day);
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m >> k;
for(int i = 1; i <= n; ++i)
cin >> A[i];
memset(dist,0x3f,sizeof dist);
for(int i = 1; i <= m; ++i){
int u,v;
cin >> u >> v;
e[u].pb(edge(v,1));
e[v].pb(edge(u,1));
}
solve();
for(int i = 1; i <= n; ++i){
if(i < n)
cout << ans[i] <<' ';
else
cout << ans[i];
}
return 0;
}
L3-1 忽远忽近的距离
题解:
本质上是单源最短路问题,先虚构出所有的质因数,并且构建相应的无向图,将所有的数和他们的质因数相连接,然后用dijkstra算法进行求解,并记录下最短路。
code
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define pb push_back
#define ff first
#define se second
#define pii pair<int,int>
const int maxn = 1e6+5;
const ll inf = 0x3f3f3f3f3f3f3f3f;
int m,n;
ll dist[2*maxn];
int done[2*maxn], vis[2*maxn], st[2*maxn];
int pre[2*maxn];
struct edge{
int to;
ll w;
edge(int a,ll b){
to = a; w = b;
};
};
vector<edge>e[2*maxn];
void prime(){
for(int i = 2; i <= 1e6; ++i){
if(vis[i])
continue;
for(int j = i; j <= 1e6; j += i){
if(st[j]){
e[j].pb({maxn+i,j/i});
e[maxn+i].pb({j,j/i});
}
if(j >= 2*i)
vis[j] = 1;
}
}
}
vector<int>path;
void print_path(int x){
for(int i = x; ;i = pre[i]){
if(i == 0)
break;
if(i <= maxn)
path.pb(i);
}
}
void dij(){
memset(dist,0x3f,sizeof dist);
dist[m] = 0;
priority_queue<pii,vector<pii>,greater<pii>>q;
q.push({0,m});
while(!q.empty()){
pii u = q.top();
q.pop();
int s = u.se;
if(done[s])
continue;
done[s] = 1;
for(int i = 0; i < e[s].size();++i){
edge t = e[s][i];
if(done[t.to])
continue;
if(dist[t.to] > dist[s] + t.w){
dist[t.to] = dist[s] + t.w;
q.push({dist[t.to],t.to});
pre[t.to] = s;
}
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int num;
cin >> num;
for(int i = 1; i <= num; ++i){
int x;
cin >> x;
st[x] = 1;
}
cin >> m >> n;
prime();
dij();
if(dist[n] == inf){
cout << "Wake up Xiaoming" <<'\n' << -1;
}else{
cout << dist[n] << '\n';
print_path(n);
for(int i = path.size()-1; i > 0;--i)
printf("%d ",path[i]);
printf("%d",path[0]);
}
return 0;
}

浙公网安备 33010602011771号