算法杂题(思维、模拟)

题目链接

A - やめて嘘はあなたらしくないよ

The h h -index of an author is the largest h h where he has at least h h papers with citations not less than h h .
Bobo has published many papers.
Given a 0 , a 1 , a 2 , , a n a_0, a_1, a_2, \dots, a_{n} which means Bobo has published a i a_i papers with citations exactly i i , find the h h -index of Bobo.
Input
The input consists of several test cases and is terminated by end-of-file.
The first line of each test case contains an integer n n .
The second line contains ( n + 1 ) (n+1) integers a 0 , a 1 , , a n a_0, a_1, \dots, a_n .
Output
For each test case, print an integer which denotes the result.
Constraint
1 n 2 1 0 5 1 \leq n \leq 2 \cdot 10^5
0 a i 1 0 9 0 \leq a_i \leq 10^9
The sum of n n does not exceed 250 , 000 250,000 .
Sample Input1
1 2
2
1 2 3
3
0 0 0 0
Sample Output1
2
0

#include<iostream>
#include<set>
#include<vector>

int a[1000005];
using namespace std;
int main() {
	int n;
	while (~scanf("%d", &n)) {
		for (int i = 0; i <= n; ++i)scanf("%d", &a[i]);
		int ans = 0;//表示论文数
		//从后往前贪心
		for (int i = n; i >= 0; --i) {
			ans += a[i];
			//如果不满足题目条件
			if (i <= ans) {
				printf("%d\n", i);
				break;
			}
		}
	}
	return 0;
}

B - 目を見てこれからのことを話そう

The h h -index of an author is the largest h h where he has at least hh papers with citations not less than h h .
Bobo has no papers and he is going to publish some subsequently.
If he works on a paper for xx hours, the paper will get ( a x ) (a⋅x) citations, where a a is a known constant.
It’s clear that x x should be a positive integer.
There is also a trick – one can cite his own papers published earlier.
Given Bobo has n n working hours, find the maximum h h -index of him.
Input
The input consists of several test cases and is terminated by end-of-file.
Each test case contains two integers n n and a a .
Output
For each test case, print an integer which denotes the maximum h h -index.
Constraint
1 n 1 0 9 1\leq n\leq 10^9
0 a n 0\leq a\leq n
The number of test cases does not exceed 1 0 4 10^4 .
Sample Input
3 0
3 1
1000000000 1000000000
Sample Output
1
2
1000000000
Hint
For the first sample, Bobo can work 3 3 papers for 1 1 hour each.
With the trick mentioned, he will get papers with citations 2 , 1 , 0 2, 1, 0 . Thus, his h h -index is 1 1 .
For the second sample, Bobo can work 2 2 papers for 1 1 and 2 2 hours respectively. He will get papers with citations 1 + 1 , 2 + 0 1 + 1, 2 + 0 . Thus, his h h -index is 2 2

最优解是每个论文都花1小时。仔细想一想就出来了。

#include<iostream>
using namespace std;
int main() {
	int n, a;
	while (~scanf("%d%d", &n, &a)) {
		printf("%d\n", (n + a) >> 1);
	}
	return 0;
}

F - my wish かなえたいのに

Bobo has n n tuples ( a 1 , b 1 , c 1 ) , ( a 2 , b 2 , c 2 ) , ( a n , b n , c n ) (a_1,b_1,c_1),(a_2,b_2,c_2)\cdots ,(a_n,b_n,c_n) .
He would like to find the lexicographically smallest permutation p 1 , p 2 , , p n p_1,p_2,\cdots ,p_n
of 1 , 2 , , n 1,2,\cdots ,n .
such that for i { 2 , 3 , , n } i∈\{2,3,…,n\}
it holds that
a p i 1 + b p i 1 a p i 1 + b p i 1 + c p i 1 a p i + b p i a p i + b p i + c p i \frac{a_{p_{i-1}}+b_{p_{i-1}}}{a_{p_{i-1}}+b_{p_{i-1}}+c_{p_{i-1}}} \leq \frac{a_{p_{i}}+b_{p_{i}}}{a_{p_{i}}+b_{p_{i}}+c_{p_{i}}}
Input
The input consists of several test cases and is terminated by end-of-file. The first line of each test case contains an integer n n .
The i t h i_{th} of the following nn lines contains 3 integers a i , b i a_i, b_i and c i c_i .
Output
For each test case, print nn integers p 1 , p 2 , , p n p_1,p_2,\cdots ,p_n seperated by spaces. DO NOT print trailing spaces.
Constraint
1 n 1 0 3 1\leq n\leq 10^3
1 a i , b i , c i 2 × 1 0 9 1≤a_i,b_i,c_i≤2×10^9
The sum of nn does not exceed 10^4
Sample Input
2
1 1 1
1 1 2
2
1 1 2
1 1 1
3
1 3 1
2 2 1
3 1 1
Sample Output
2 1
1 2
1 2 3

除法化乘法避免精度损失,在优化一下乘法(卡long long上限)。

#include<iostream>
#include<set>
#include<vector>
#include<algorithm>
using namespace std;
struct Node {
	long long a, b, c;
	int node;
};
Node Data[1001];
int main() {
	int n;
	while (~scanf("%d", &n)) {
		for (int i = 1; i <= n; ++i) {
			scanf("%lld%lld%lld", &Data[i].a, &Data[i].b, &Data[i].c);
			Data[i].node = i;
		}
		sort(Data + 1, Data + n + 1, [](Node&Left, Node&Right) {
			long long&&left = (Left.a + Left.b)*(Right.c),
				&&right = (Left.c)*(Right.a + Right.b);
			return (left == right ? Left.node < Right.node:left < right);
			});
		for (int i = 1; i < n; ++i) {
			printf("%lld ", Data[i].node);
		}
		printf("%lld", Data[n].node);
		putchar('\n');
	}
	return 0;
}

G - すべては God knows…

Bobo has a string S=s1s2…sn consists of letter a, b and c.
He can transform the string by inserting or deleting substrings aa, bb and abab.
Formally, A=u∘w∘v (``∘’’ denotes string concatenation) can be transformed into A′=u∘v and vice versa where u, v are (possibly empty) strings and w∈{aa,bb,abab}.
Given the target string T = t 1 t 2 t m T=t_1t_2\cdots t_m , determine if Bobo can transform the string S into T.
Input
The input consists of several test cases and is terminated by end-of-file.
The first line of each test case contains a string s 1 s 2 s n s_1s_2\cdots s_n .
The second line contains a string t 1 t 2 t m t_1t_2\cdots t_m .
Output
For each test case, print Yes if Bobo can. Print No otherwise.
Constraint
1 n , m 1 0 4 1≤n,m≤10^4
s 1 , s 2 , , s n , t 1 , t 2 , , t m { a , b , c } s_1,s_2,\cdots ,s_n,t_1,t_2,\cdots ,t_m∈\{a,b,c\}
The sum of n and m does not exceed 250,000.
Sample Input
ab
ba
ac
ca
a
ab
Sample Output
Yes
No
No
Hint
For the first sample, Bobo can transform as ab => aababb => babb => ba.

根据提示,ab可以转为baba同理。且可以增加删除aabb,那么,在没有c的字符串中,只要统计两个字符串中ab个数是否同奇同偶即可。而对于c,可以看作c将字符串分割成了若干子串。

#include<iostream>
#include<string>
#define scanf scanf_s
int ans1[10001], ans2[10001];
using namespace std;string a, b;

int main() {
	while (cin >> a >> b) {
		int t = 0;
		int ct = 0;
		for (int i = 0; i < a.size(); ++i) {
			if (a[i] == 'c') {
				ans1[ct++] = t;
			}
			else {
				t ^= a[i];
			}
		}
		ans1[ct++] = t;
		int s = 0;
		int st = 0;
		for (int i = 0; i<b.size(); ++i) {
			if (b[i] == 'c') {
				ans2[st++] = s;
			}
			else {
				s ^= b[i];
			}
		}
		ans2[st++] = s;
		bool flag = false;
		if (st == ct) {
			for (int i = 0; i < st; ++i) {
				if (ans1[i] != ans2[i]) {
					puts("No");
					flag = true;
					break;
				}
			}
			if (!flag) {
				puts("Yes");
			}
		}
		else {
			puts("No");
		}
	}
	return 0;
}

K - 傷跡なぞる

Given a , b , c , d a,b,c,d find out the number of pairs of integers ( x , y ) (x,y) where a x b , c y d a≤x≤b,c≤y≤d and x y x*y is a multiple of 2018.
Input
The input consists of several test cases and is terminated by end-of-file.
Each test case contains four integers a , b , c , d a,b,c,d .
Output
For each test case, print an integer which denotes the result.
Constraint
1 a b 1 0 9 , 1 c d 1 0 9 1≤a≤b≤10^9,1≤c≤d≤10^9
The number of tests cases does not exceed 1 0 4 10^4 .
Sample Input
1 2 1 2018
1 2018 1 2018
1 1000000000 1 1000000000
Sample Output
3
6051
1485883320325200

2018的公约数只有1*2018以及2*1009这两对,根据容斥定理很容易求出结果。

#include<iostream>
#include<set>
#include<vector>
using namespace std;
long long a, b, c, d;
int main() {
	while (~scanf("%lld%lld%lld%lld", &a, &b, &c, &d)) {
		long long left[4], right[4];

		auto fuck = [](long long Array[4],long long &left,long long &right)->void {
			Array[0] = right - left + 1;
			Array[1] = right / 2 - (left - 1) / 2;
			Array[2] = right / 1009 - (left - 1) / 1009;
			Array[3] = right / 2018 - (left - 1) / 2018;
			Array[2] -= Array[3];
			Array[1] -= Array[3];
			Array[0] -= Array[3] + Array[2] + Array[1];
		};

		fuck(left, a, b);
		fuck(right, c, d);

		const long long&&Ans =
			left[0] * right[3] +
			left[1] * (right[2] + right[3]) +
			left[2] * (right[1] + right[3]) +
			left[3] * (right[0] + right[1] + right[2] + right[3]);

		printf("%lld\n", Ans);
	}
	return 0;
}
发布了20 篇原创文章 · 获赞 22 · 访问量 2489

猜你喜欢

转载自blog.csdn.net/qq_42971794/article/details/103545584