【ShanDong Multi-University Training #3】部分题解

比赛地址:ShanDong Multi-University Training #3 - Virtual Judge

比赛地址:ShanDong Multi-University Training #3 - Virtual Judge

A - Booby Prize

不难发现,最后释放的蚂蚁力量值必定是这个区间的最大公约数,而且这个最大公约数是这个区间的最小值才符合题意,只需要用线段树处理一下区间GCD、区间最小值、区间最小值的个数。如果区间gcd与区间最小值相同,就可以输出区间长度减去最小值的个数,反之,输出区间的长度

代码:

(参考Codeforces 474F(分块)_hollowstory的博客-CSDN博客

#include<bits/stdc++.h>

using namespace std;

const int N = 1e5+6;
const int M = 506;

int n,t,s[N],l,r;
int unit,siz,ans[M][M],gans[M][M];
int g,temp,cnt;

int gcd(int a,int b)
{
return b ? gcd(b, a % b) : a;

 }
int main()
{
memset(ans,0,sizeof ans);
memset(gans, 0, sizeof gans);

scanf("%d",&n):
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
unit = sqrt(n);
    siz = (n + unit) / unit;

    for(int i = 0; i <= n; i += unit){
        g = s[i + 1], cnt = 0, temp;
        for(int j = i; j <= n; j++){
            temp = gcd(g, s[j]);
            if(g != temp) cnt = 0, g = temp;
            if(s[j] == g) cnt++;
            if(j % unit == 0) ans[i / unit][j / unit] = cnt, gans[i / unit][j / unit] = g;
        }
        ans[i / unit][siz] = cnt;
        gans[i / unit][siz] = g; 
    }

    scanf("%d", &t);
    while(t--){
        scanf("%d%d", &l, &r);
        int x = (l + unit) / unit * unit, y = r / unit * unit;
        int res;
        if(x >= y) g = s[l], res = 1, x = y = l;
        else g = gans[x / unit][y / unit], res = ans[x / unit][y / unit];

        for(int i = l; i < x; i++){
            temp = gcd(g, s[i]);
            if(g != temp) res = 0, g = temp;
            if(g == s[i]) res++;
        }
        for(int i = y + 1; i <= r; i++){
            temp = gcd(g, s[i]);
            if(g != temp) res = 0, g = temp;
            if(g == s[i]) res++;
        }

        printf("%d\n", r - l + 1 - res);
    }

    return 0;


}

B - New String

写一个bool类型的cmp函数,然后使用带cmp限制的sort即可

代码:

#include <bits/stdc++.h>
using namespace std;

#define MAX 300000 + 50
int n, m, k, op;
string s;
map<char, int>mp;
struct ran
{
    string s;
    bool operator < (const ran &x)const{
        for(int i = 0; i < s.size() && i < x.s.size(); ++i){
            if(mp[s[i]] < mp[x.s[i]])return true;
            else if(mp[s[i]] > mp[x.s[i]])return false;
            else continue;
        }
        return s.size() < x.s.size();
    }
}tr[MAX];

void work(){
    cin >> s;
    for(int i = 0; i < s.size(); ++i){
        mp[s[i]] = i + 1;
    }
    cin >> n;
    for(int i = 1; i <= n; ++i){
        cin >> tr[i].s;
    }
    sort(tr + 1, tr + 1 + n);
    cin >> k;
    cout << tr[k].s << endl;
}


int main()
{
    work();
    return 0;
}

C - Easy Problem

emmm...看一眼范围,发现不能爆搜,结果题解说就是爆搜(QAQ

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 60;
char g[N][N];int n;
bool vis[N][N][N][N];
struct node
{
	int x1, y1;
	int x2, y2;
	int cnt;
};
int xa,xb,ya,yb;
void bfs()
{
	queue<node> q;
 
	int dx[] = {-1, 1, 0, 0};
	int dy[] = {0, 0, 1, -1};
	q.push({xa, ya, xb, yb, 0});
	while(q.size())
	{
		auto t = q.front();
		q.pop();
		if(t.x1 == t.x2 && t.y1 == t.y2) {
			cout << t.cnt << '\n';
			return;
		}
		for (int i = 0; i < 4; i ++ ) {
			int nx1 = t.x1 + dx[i];
			int ny1 = t.y1 + dy[i];
			int nx2 = t.x2 + dx[i];
			int ny2 = t.y2 + dy[i];
			
			if(nx1 < 1 || nx1 > n)nx1 = t.x1;
			if(nx2 < 1 || nx2 > n)nx2 = t.x2;
			if(ny1 < 1 || ny1 > n)ny1 = t.y1;
			if(ny2 < 1 || ny2 > n)ny2 = t.y2;
			if(g[nx1][ny1] == '*')nx1 = t.x1, ny1 = t.y1;
			if(g[nx2][ny2] == '*')nx2 = t.x2, ny2 = t.y2;
 
			if(vis[nx1][ny1][nx2][ny2])continue;
			vis[nx1][ny1][nx2][ny2] = 1;
			q.push({nx1, ny1, nx2, ny2, t.cnt + 1});
		}
	}
	cout << "no solution\n";
}
 
int main(){
	std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
 	cin >> n;
 	for (int i = 1; i <= n; i ++ ) {
 		for (int j = 1; j <= n; j ++ ) {
 			cin >> g[i][j];
 			if(g[i][j] == 'a') {
 				xa = i;
 				ya = j;
 			} else if(g[i][j] == 'b') {
 				xb = i;
 				yb = j;
 			}
 		}
 	}   
 
 	bfs();
	return 0;
}

G - Optimal Biking Strategy(DP + 二分)

代码( sjh orz):

#include<bits/stdc++.h>

typedef long long ll;
using namespace std;

const int N = 1e6 + 10;
int f[N][N];
int a[N];
int main()
{
	std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n, p, s, t;
    cin >> n >> p >> s;
   	for (int i = 1; i <= n; i ++ ) cin >> a[i];
   	cin >> t;
 
   	for (int i = 0; i < t; i ++ ) f[0][i] = 0;
 
   	for (int i = 1; i <= n; i ++ )
   		for (int j = 0; j <= t; j ++ ) {
   			f[i][j] = f[i - 1][j] + a[i] - a[i - 1];
   		for (int k = 1; k <= j; k ++ ) {
   				int mx = k * s;
   				int ans = -1;
   				int l = 1, r = i;
   				while(l <= r) {
   					int mid = (l + r)>>1;
   					if(a[i] - a[mid] < mx) {
   						r = mid - 1;
   						ans = mid;
   					}
   					else if(a[i] - a[mid] == mx) {
   						ans = mid;
   						break;
   					}
   					else l = mid + 1;
   				}
   				if(ans == -1)continue;
   				f[i][j] = min(f[i][j], f[ans][j - k]);

 
   			}
   		}
   	int ans = 0x3f3f3f3f;
   	for (int i = 1; i <= n; i ++ ) {
   		ans = min(ans, f[i][t] + p - a[i]);
   	}
   	cout << ans << '\n';
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对不起,由于我是一个文本交互的模型,我无法提供图像内容或直接链接到具体的题解或解决方案。但是,我可以帮你理解CSP-J2019公交换乘问题的基本概念和解决策略,这通常涉及到数据结构、图论以及算法设计。 CSP-J2019中的公交换乘问题可能是一个典型的旅行商问题(Traveling Salesman Problem, TSP)变种,或者是寻找最优路径的问题,其中涉及到公交网络中不同站点之间的最短路径或最少换乘次数。解决此类问题通常需要使用动态规划、贪心算法或者一些启发式搜索算法,比如A*搜索或Dijkstra算法。 如果你需要了解题目的基本思路,可能会这样操作: 1. 建立一个图,节点代表公交站点,边代表两个站点之间的路线及其长度或换乘次数。 2. 对于每个节点,计算从起点到所有其他节点的最短路径,形成一个邻接矩阵或邻接表。 3. 使用动态规划方法,例如记忆化搜索,尝试所有可能的路径,每次选择当前未访问节点中距离最近的一个,直到遍历完所有节点并回到起点,记录下总的距离或换乘次数。 4. 为了优化,可以考虑使用启发式搜索策略,如用估算的总距离作为启发信息,优先探索看起来更优的路径。 如果你对具体解法有疑问,或者想了解某个步骤的详细操作,请告诉我,我会尽力解释。至于详细的题解,建议你查阅相关的代码库、论坛帖子或在线教程,它们通常会有文字描述和步骤示例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值