算法杂题(思维、模拟)

题目链接

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

The h h h-index of an author is the largest h h h where he has at least h h h papers with citations not less than h 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} a0,a1,a2,,an which means Bobo has published a i a_i ai papers with citations exactly i i i, find the h 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 n.
The second line contains ( n + 1 ) (n+1) (n+1) integers a 0 , a 1 , … , a n a_0, a_1, \dots, a_n a0,a1,,an.
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 1n2105
0 ≤ a i ≤ 1 0 9 0 \leq a_i \leq 10^9 0ai109
The sum of n n n does not exceed 250 , 000 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 h-index of an author is the largest h h h where he has at least hh papers with citations not less than h 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) (ax) citations, where a a a is a known constant.
It’s clear that x 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 n working hours, find the maximum h 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 n and a a a.
Output
For each test case, print an integer which denotes the maximum h h h-index.
Constraint
1 ≤ n ≤ 1 0 9 1\leq n\leq 10^9 1n109
0 ≤ a ≤ n 0\leq a\leq n 0an
The number of test cases does not exceed 1 0 4 10^4 104.
Sample Input
3 0
3 1
1000000000 1000000000
Sample Output
1
2
1000000000
Hint
For the first sample, Bobo can work 3 3 3 papers for 1 1 1 hour each.
With the trick mentioned, he will get papers with citations 2 , 1 , 0 2, 1, 0 2,1,0. Thus, his h h h-index is 1 1 1.
For the second sample, Bobo can work 2 2 2 papers for 1 1 1 and 2 2 2 hours respectively. He will get papers with citations 1 + 1 , 2 + 0 1 + 1, 2 + 0 1+1,2+0. Thus, his h h h-index is 2 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 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) (a1,b1,c1),(a2,b2,c2),(an,bn,cn).
He would like to find the lexicographically smallest permutation p 1 , p 2 , ⋯   , p n p_1,p_2,\cdots ,p_n p1,p2,,pn
of 1 , 2 , ⋯   , n 1,2,\cdots ,n 1,2,,n.
such that for i ∈ { 2 , 3 , … , n } 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}}} api1+bpi1+cpi1api1+bpi1api+bpi+cpiapi+bpi
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 n.
The i t h i_{th} ith of the following nn lines contains 3 integers a i , b i a_i, b_i ai,bi and c i c_i ci.
Output
For each test case, print nn integers p 1 , p 2 , ⋯   , p n p_1,p_2,\cdots ,p_n p1,p2,,pn seperated by spaces. DO NOT print trailing spaces.
Constraint
1 ≤ n ≤ 1 0 3 1\leq n\leq 10^3 1n103
1 ≤ a i , b i , c i ≤ 2 × 1 0 9 1≤a_i,b_i,c_i≤2×10^9 1ai,bi,ci2×109
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 T=t1t2tm, 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 s1s2sn.
The second line contains a string t 1 t 2 ⋯ t m t_1t_2\cdots t_m t1t2tm.
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 1n,m104
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\} s1,s2,,sn,t1,t2,,tm{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 a,b,c,d find out the number of pairs of integers ( x , y ) (x,y) (x,y) where a ≤ x ≤ b , c ≤ y ≤ d a≤x≤b,c≤y≤d axb,cyd and x ∗ y x*y xy 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 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 1ab109,1cd109
The number of tests cases does not exceed 1 0 4 10^4 104.
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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值