1. 程式人生 > 實用技巧 >操作cookie

操作cookie

A. Replacing Elements


#include <bits/stdc++.h>
using namespace std;
const int N = 100 + 20;

int n, d, a[N];

int main()
{
	// freopen("A.in", "r", stdin);
	int __;
	scanf("%d", &__);
	while(__ -- )
	{
		scanf("%d%d", &n, &d);
		for(int i = 1; i <= n; ++ i) scanf("%d", &a[i]);
		sort(a + 1, a + n + 1);
		if(a[n] <= d) puts("YES");
		else if(a[1] + a[2] <= d) puts("YES");
		else puts("NO");
	}
	return 0;
}

B. String LCM


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

#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)

int n;

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

int main()
{
	// freopen("B.in", "r", stdin);
	IOS;
	int __;
	cin >> __;
	while(__ -- )
	{
		string a, b;
		cin >> a >> b;
		int len = gcd(a.size(), b.size());
		string aa, bb;
		for(int i = 0; i < (int)b.size() / len; ++ i) aa += a;
		for(int i = 0; i < (int)a.size() / len; ++ i) bb += b;
		if(aa == bb) cout << aa << endl;
		else cout << "-1" << endl;
	}
	return 0;
}

C. No More Inversions


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

const int N = 2e5 + 20;

int n, k;
int a[N];

int main()
{
	// freopen("C.in", "r", stdin);
	int __;
	scanf("%d", &__);
	while(__ -- )
	{
		scanf("%d%d", &n, &k);
		for(int i = 1; i < 2 * k - n; ++ i) printf("%d ", i);
		for(int i = k; i >= 2 * k - n; -- i) printf("%d ", i);
		puts("");
	}

	return 0;
}

D. Program

維護一個字首最大值最小值和一個字尾最大值最小值即可


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

const int N = 2e5 + 20;

int n, m;
int pre_max[N], pre_min[N];
int post_max[N], post_min[N];
int val[N];
char s[N];

int main()
{
	// freopen("D.in", "r", stdin);
	int __;
	scanf("%d", &__);
	while(__ -- )
	{
		scanf("%d%d", &n, &m);
		scanf("%s", s + 1);
		for(int i = 1; i <= n; ++ i)
			val[i] = val[i - 1] + (s[i] == '+' ? 1 : -1);
		pre_max[1] = pre_min[1] = val[1];
		for(int i = 2; i <= n; ++ i)
		{
			pre_max[i] = max(pre_max[i - 1], val[i]);
			pre_min[i] = min(pre_min[i - 1], val[i]);
		}
		post_min[n] = post_max[n] = val[n]; 
		for(int i = n - 1; i >= 1; -- i)
		{
			post_max[i] = max(post_max[i + 1], val[i]);
			post_min[i] = min(post_min[i + 1], val[i]);
		}
		for(int i = 1; i <= m; ++ i)
		{
			int l, r;
			scanf("%d%d", &l, &r);
			int maxres = 0, minres = 0;
			if(l > 1) 
			{
				maxres = max(maxres, pre_max[l - 1]);
				minres = min(minres, pre_min[l - 1]); 
			}
			if(r < n) 
			{
				int tmp = val[r] - val[l - 1];
				maxres = max(maxres, post_max[r + 1] - tmp);
				minres = min(minres, post_min[r + 1] - tmp);
			}
			printf("%d\n", maxres + abs(minres) + 1);
		}
	}
	return 0;
}

E. Minimum Path

找到一條路徑,使得 路徑長度 - 最長邊 + 最短邊 的值最大.
建一個4層的分層圖,1向2,3向4建(x, y, 0), 表示該邊是最長邊,1向3,2向4建(x, y, 2 * z),表示該邊是最短邊,1向4建(x, y, z)表示該邊既是最長邊也是最短邊.
然後求最短路即可.


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

typedef long long LL;
const LL INF = 1e18;
const int N = 2e5 + 20;

struct Edge
{
	int to, nxt, w;
}line[N * 20];
int fist[N * 4], idx;
int n, m;

void add(int x, int y, int z)
{
	line[idx] = (Edge){y, fist[x], z};
	fist[x] = idx ++;
}

void addedge(int x, int y, int z)
{
	add(x, y, z); add(x + n, y + n, z);
	add(x + 2 * n, y + 2 * n, z); add(x + 3 * n, y + 3 * n, z);

	add(x, y + n, 0); add(x + 2 * n, y + 3 * n, 0);
	add(x, y + 2 * n, 2 * z); add(x + n, y + 3 * n, 2 * z);
	add(x, y + 3 * n, z);
}

bool st[N * 4];
LL dis[N * 4];
struct zt
{
	int x;
	LL d;
};
bool operator < (zt a, zt b)
{
	return a.d > b.d;
}

void heap_dijkstra()
{
	priority_queue<zt> q;
	for(int i = 1; i <= 4 * n; ++ i) dis[i] = INF;
	dis[1] = 0;
	q.push((zt){1, 0});
	while(!q.empty())
	{
		zt u = q.top(); q.pop();
		if(st[u.x]) continue;
		st[u.x] = 1;
		for(int i = fist[u.x]; i != -1; i = line[i].nxt)
		{
			int v = line[i].to;
			if(dis[v] > dis[u.x] + line[i].w)
			{
				dis[v] = dis[u.x] + line[i].w;
				q.push((zt){v, dis[v]});
			}
		}
	}
}

int main()
{
	// freopen("E.in", "r", stdin);
	memset(fist, -1, sizeof fist);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; ++ i)
	{
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		addedge(a, b, c);
		addedge(b, a, c);
	}
	heap_dijkstra();
	for(int i = 2; i <= n; ++ i)
		printf("%lld ", dis[i + 3 * n]);
	puts("");
	return 0;
}

另一種寫法,可以寫成dis[i][0/1][0/1]表示當前狀態,用狀態轉移的形式選擇當前邊是否是最長邊或最短邊.


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

typedef long long LL;
const LL INF = 1e18;
const int N = 2e5 + 20;

int n, m;
int fist[N], idx;
struct Edge
{
	int to, nxt, w;
}line[N * 2];

void add(int x, int y, int z)
{
	line[idx] = (Edge){y, fist[x], z};
	fist[x] = idx ++;
}

bool st[N][2][2];
LL dis[N][2][2];

struct zt
{
	int x, t1, t2;
	LL d;
};
bool operator < (zt a, zt b)
{
	return a.d > b.d;
}

void heap_dijkstra()
{
	priority_queue<zt> q;
	for(int i = 1; i <= n; ++ i) 
		for(int j = 0; j <= 1; ++ j)
			for(int k = 0; k <= 1; ++ k)
				dis[i][j][k] = INF;
	dis[1][0][0] = 0;
	q.push((zt){1, 0, 0, 0});
	while(!q.empty())
	{
		zt u = q.top(); q.pop();
		if(st[u.x][u.t1][u.t2]) continue;
		st[u.x][u.t1][u.t2] = 1;
		for(int i = fist[u.x]; i != -1; i = line[i].nxt)
		{
			int v = line[i].to;
			if(dis[v][u.t1][u.t2] > dis[u.x][u.t1][u.t2] + line[i].w)
			{
				dis[v][u.t1][u.t2] = dis[u.x][u.t1][u.t2] + line[i].w;
				q.push((zt){v, u.t1, u.t2, dis[v][u.t1][u.t2]});
			}
			if(!u.t1 && dis[v][1][u.t2] > dis[u.x][u.t1][u.t2] + 0)
			{
				dis[v][1][u.t2] = dis[u.x][u.t1][u.t2];
				q.push((zt){v, 1, u.t2, dis[v][1][u.t2]});
			}
			if(!u.t2 && dis[v][u.t1][1] > dis[u.x][u.t1][u.t2] + 2 * line[i].w)
			{
				dis[v][u.t1][1] = dis[u.x][u.t1][u.t2] + 2 * line[i].w;
				q.push((zt){v, u.t1, 1, dis[v][u.t1][1]});
			}
			if(!u.t1 && !u.t2 && dis[v][1][1] > dis[u.x][u.t1][u.t2] + line[i].w)
			{
				dis[v][1][1] = dis[u.x][u.t1][u.t2] + line[i].w;
				q.push((zt){v, 1, 1, dis[v][1][1]});
			}
		}
	}
}

int main()
{
	// freopen("E.in", "r", stdin);
	memset(fist, -1, sizeof fist);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; ++ i)
	{
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		add(a, b, c);
		add(b, a, c);
	}
	heap_dijkstra();
	for(int i = 2; i <= n; ++ i)
		printf("%lld ", dis[i][1][1]);
	puts("");
	return 0;
}

2021.1.19