dengch

 

atcoder320

A

A - Leyland Number
题目概述:计算AB + BA
解题思路:由于数据范围较小,可以直接使用循环来做。但是我这里用的是pow()函数,但是需要注意的是pow()函数可能会有浮点数陷阱,所以尽可能要避免使用该函数。

点击查看代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <vector>
#include <map>
#include <set>
#include <cmath>

using namespace std;

typedef long long LL;
typedef pair<int,int>PII;

map<string,int>ma;

const int N = 110;
int p[N];

int main(){
	
	int a,b;
	cin >> a >> b;

	int res = pow(a,b) + pow(b,a);

	cout << res << endl;	


	return 0;
}

B

B-Longest Palindrome
题目概述:给定以字符串,需要我们求出其最长连续回文子串。
解题思路:由于题目数据范围较小,直接暴力枚举其所有子串,并判断是否是回文串,再更新答案即可

点击查看代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <vector>
#include <map>
#include <set>

using namespace std;

typedef long long LL;
typedef pair<int,int>PII;


int main(){
	string str;
	cin >> str;

	int n = str.size();

	int maxlen = -1;
	for(int i = 0; i < n; i ++)
		for(int j = 0; i + j <= n; j ++){
			string subs = str.substr(i,j);
			//cout << subs << endl;
			string src = subs;
			reverse(subs.begin(),subs.end());
			if(src == subs)maxlen = max(maxlen,(int)src.size());
		}

		cout << maxlen << endl;

	return 0;
}

C

C - Slot Strategy 2 (Easy)
题目概述:有三个转盘(注意只有三个),每个转盘上有M个数字(0-9)。在0时刻,三个转盘都开始转动,在任意时刻你可以决定让其中一个转盘停下,问至少需要多长时间,你才能让三个转盘停下时显示的数字保持一致。
解题思路:由于数据范围较小,所以直接暴力枚举转盘停下时的每种情况。时间复杂度为\(O(N^3)\)

点击查看代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <vector>
#include <map>
#include <set>
#include <queue>

using namespace std;

typedef long long LL;
typedef pair<int,int>PII;
const int INF = 1e9;


int main(){

	int M;
	cin >> M;
	string str[3];
	for(int i = 0; i < 3; i ++)cin >> str[i];

	int res = INF;
	//遍历每种情况
	for(int i = 0; i < M; i ++){
		for(int j = 0; j < M; j ++){
			for(int p = 0; p < M; p ++){
				if(str[0][i] != str[1][j] || str[0][i] != str[2][p])continue;
					int t[3]{i,j,p};
					//判断是否有相同的操作时间
					if(t[0] == t[1])t[1] += M;
					if(t[2] == t[0])t[2] += M;
					if(t[2] == t[1])t[2] += M;
					res = min(res,max({t[1],t[2],t[0]}));
			}
		}
	}

	if(res == INF)res = -1;
	cout << res << endl;



	return 0;
}

D

D - Relative Position
题目概述:给定1号点的坐标(0,0)以及M条信息(某两个点的相对坐标),问我们最终是否能够确定每个点的坐标,并输出。
解题思路:这种题型可以抽象为,用已知去推未知。可以使用dfs或bfs求解。我这里用的是bfs

点击查看代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <vector>
#include <map>
#include <set>
#include <queue>

using namespace std;

typedef long long LL;
typedef pair<int,int>PII;
const int N = 200010,INF = 0x3f3f3f3f;
bool st[N];
LL x[N],y[N];
int n,m;
struct pos{
	int b,c,d;
};
queue<int>q;
vector<pos>v[N];

int main(){

	cin >> n >> m;
	//cout << INF << endl;
	memset(x,0x3f,sizeof x);
	memset(y,0x3f,sizeof y);

	st[1] = true;
	x[1] = 0,y[1] = 0;
	while(m --){
		int a,b,c,d;
		cin >> a >> b >> c >> d;

		v[a].push_back({b,c,d});
		v[b].push_back({a,-c,-d});
	}

	q.push(1);
	while(q.size()){
		int t = q.front();
		q.pop();

		for(auto ele : v[t]){
			
			int b = ele.b,c = ele.c,d = ele.d;
			if(!st[b]){
				st[b] = true;
				q.push(b);
				x[b] = (LL)x[t] + c,y[b] = (LL)y[t] + d;
			}
		}
	}

	for(int i = 1; i <= n; i ++){
		if(x[i] > 3 * 1e14 || y[i] > 3 * 1e14)puts("undecidable");
		else cout << x[i] << " " << y[i] << endl;
	}


	return 0;
}

E

E - Somen Nagashi
题目概述:有n个人排队吃面,在T_i时刻会有W_i的面流下,排在前面的人可以得到该数量的面,并离开队列,在s_i后将会返回队列,并且是原来的位置。问当所有事件结束后,每个人得到的面条的数量。
解题思路:这种题型可以归为事件类题型,我们可以抽象出两个基本事件。1.就是题目中的面条流下事件;2. 得到面条的人离开队列以及在s_i后回归队列。可以使用STL中set来维护这两个事件。

点击查看代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#include <queue>

//#define x first 
//#define  y second
using namespace std;

typedef long long LL;
typedef pair<LL,LL>PLL;
const int N = 200010;

struct Event{
	int t,w,s;

	bool operator<(const Event &b)const{
	    if(this->t != b.t)return this->t < b.t;
	    else if(this->w != b.w)return this->w < b.w;
	    return this->s < b.s;
	}
};

LL res[N];
set<int>q;
set<Event>event;

int main(){
	int n,m;
	cin >> n >> m;

	for(int i = 1; i <= n; i ++){
		q.insert(i);
	}

	while(m --){
		int t,s,w;
		cin >> t >> w >> s;
		event.insert({t,w,s});
	}

	while(event.size()){
		auto x = *event.begin();

		event.erase(x);
		//判断是那种事件
		if(x.w < 0)q.insert(-x.w);
		else{
			//队列中没有人
			if(!q.size())continue;
			else{
				//通过迭代器取值
				auto t = *q.begin();
				//从队列中删去
				q.erase(t);
				res[t] = (LL)res[t] + x.w;
				//增加一个事件,由于回归队列事件需排在面留下事件后,我们使其为负数
				event.insert({x.t + x.s,-t,0});
			}
		}
	}

	for(int i = 1; i <= n; i ++)cout << res[i] << endl;

	
	return 0;
}

F

F - Fuel Round Trip
题目概述:驾驶一辆储油量为H的汽车从起点到终点往返一次,每两点之间的距离就是耗油量,只能从一个点到其相邻点。途中有n-1个加油站,问最少需要多少钱才能往返一次,如果不行输出-1.
解题思路:同时考虑去程和回程的dp

点击查看代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX_SIZE = 301;
// dp[pos][v1][v2] 代表只考虑 X_1 ~ X_pos,
// 去程至 X_pos 时恰有 v1 的油,回程至 X_pos 至多有 v2 的油至少要花多少钱
int dp[MAX_SIZE][MAX_SIZE][MAX_SIZE];
void update(int &x, int v) {
    if(x == -1 || x > v) {
        x = v;
    }
}
int main() {
    int N, H, X[MAX_SIZE], P[MAX_SIZE], F[MAX_SIZE];
    cin >> N >> H;
    X[0] = 0;
    for(int i = 1; i <= N; i++) {
        cin >> X[i];
    }
    for(int i = 1; i < N; i++) {
        cin >> P[i] >> F[i];
    }
    memset(dp, -1, sizeof(dp));
    dp[0][H][0] = 0;
    for(int pos = 0; pos < N - 1; pos++) {
        int dis = X[pos + 1] - X[pos];
        for(int v1 = 0; v1 <= H; v1++) {
            for(int v2 = 0; v2 <= H; v2++) {
                if(dp[pos][v1][v2] == -1) continue;
                if(v2 + 1 <= H) {
                    update(dp[pos][v1][v2 + 1], dp[pos][v1][v2]);
                }
                //判断能否到达下一点
                if(v1 >= dis && v2 + dis <= H) {
                    // 在位置 pos + 1 不加油
                    update(dp[pos + 1][v1 - dis][v2 + dis], dp[pos][v1][v2]);
                    // 位置 pos + 1 给去程加油
                    update(dp[pos + 1][min(v1 - dis + F[pos + 1], H)][v2 + dis], dp[pos][v1][v2] + P[pos + 1]);
                    // 位置 pos + 1 给回程加油
                    if(v2 + dis >= F[pos + 1]) {
                        update(dp[pos + 1][v1 - dis][v2 + dis - F[pos + 1]], dp[pos][v1][v2] + P[pos + 1]);
                    }
                }
            }
        }
    }
    int last_dis = (X[N] - X[N - 1]) * 2;
    int answer = -1;
    for(int v1 = 0; v1 <= H; v1++) {
        for(int v2 = 0; v2 <= H; v2++) {
            if(dp[N - 1][v1][v2] == -1) continue;
            if(v1 - last_dis >= v2) {
                update(answer, dp[N - 1][v1][v2]);
            }
        }
    }
    cout << answer << '\n';
}

posted on 2023-09-23 11:12  BkDench  阅读(16)  评论(0)    收藏  举报

导航