A. K-divisible Sum

You are given two integers n and k.

You should create an array of n positive integers a1,a2,…,an such that the sum (a1+a2+⋯+an) is divisible by k and maximum element in a is minimum possible.

What is the minimum possible maximum element in a?

Input
The first line contains a single integer t (1≤t≤1000) — the number of test cases.

The first and only line of each test case contains two integers n and k (1≤n≤109; 1≤k≤109).

Output
For each test case, print one integer — the minimum possible maximum element in array a such that the sum (a1+⋯+an) is divisible by k.

Example
inputCopy
4
1 5
4 3
8 8
8 17
outputCopy
5
2
1
3
Note
In the first test case n=1, so the array consists of one element a1 and if we make a1=5 it will be divisible by k=5 and the minimum possible.

In the second test case, we can create array a=[1,2,1,2]. The sum is divisible by k=3 and the maximum is equal to 2.

In the third test case, we can create array a=[1,1,1,1,1,1,1,1]. The sum is divisible by k=8 and the maximum is equal to

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
//#include <ext/rope>
#include <bits/stdc++.h> 

using namespace std;

#define gt(x) x = read()
#define int  long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
//#define x first
//#define y second

int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0}; 

//typedef __int128 INT;
typedef pair<double, int> PDI;
typedef pair<int, int> PII;
typedef unsigned long long ULL;

inline int read(int out = 0)
{
    char c;
    while((c=getchar()) < 48 || c > 57);
    while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
    return out; 
}

const int N = 1010;
const int M = 4 * N;
const int mod = 1e4 + 7;
const int PP = 13331;
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const double PI = acos(-1);

int yy[N];

void init1(){
	for (int i = 1; i <= 124; i ++)   yy[i] = 103;
}

void init2(){
	for (int i = 1; i <= 23; i ++)   yy[i] = i + 1;
}

signed main(){
	int T;
	scanf("%lld", &T);
	while(T --){
		int n, k;
		scanf("%lld%lld", &n, &k);
	//	int temp = k;
	//	int idx = 2;
		if (n > k){
			int cnt = n / k;
			//cout << cnt << "---" << endl;
			if (n % k != 0)   cnt ++;                              
			k = k * cnt;
		} 
		
		int ans = (k + n - 1) / n;
		printf("%lld\n", ans);
	}
	
	return 0;
}

B. Inflation
You have a statistic of price changes for one product represented as an array of n positive integers p0,p1,…,pn−1, where p0 is the initial price of the product and pi is how the price was increased during the i-th month.

Using these price changes you are asked to calculate the inflation coefficients for each month as the ratio of current price increase pi to the price at the start of this month (p0+p1+⋯+pi−1).

Your boss said you clearly that the inflation coefficients must not exceed k %, so you decided to increase some values pi in such a way, that all pi remain integers and the inflation coefficients for each month don’t exceed k %.

You know, that the bigger changes — the more obvious cheating. That’s why you need to minimize the total sum of changes.

What’s the minimum total sum of changes you need to make all inflation coefficients not more than k %?

Input
The first line contains a single integer t (1≤t≤1000) — the number of test cases.

The first line of each test case contains two integers n and k (2≤n≤100; 1≤k≤100) — the length of array p and coefficient k.

The second line of each test case contains n integers p0,p1,…,pn−1 (1≤pi≤109) — the array p.

Output
For each test case, print the minimum total sum of changes you need to make all inflation coefficients not more than k %.

Example
inputCopy
2
4 1
20100 1 202 202
3 100
1 1 1
outputCopy
99
0
Note
In the first test case, you can, for example, increase p0 by 50 and p1 by 49 and get array [20150,50,202,202]. Then you get the next inflation coefficients:

5020150≤1100;
20220150+50≤1100;
20220200+202≤1100;
In the second test case, you don’t need to modify array p, since the inflation coefficients are already good:

11≤100100;
11+1≤100100;

从后往前枚举,要注意的是要除k,因为是k倍,既然是加,那么加到第一个数对后面的都有效,是最好的,那么直接加到第一个数即可

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>


using namespace std;

#define gt(x) x = read()
#define int  long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
//#define x first
//#define y second

int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0}; 

typedef pair<double, int> PDI;
typedef pair<int, int> PII;
typedef unsigned long long ULL;

inline int read(int out = 0)
{
    char c;
    while((c=getchar()) < 48 || c > 57);
    while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
    return out; 
}

const int N = 1010;
const int M = 4 * N;
const int mod = 1e4 + 7;
const int PP = 13331;
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const double PI = acos(-1);

int yy[N];

void init1(){
	for (int i = 1; i <= 124; i ++)   yy[i] = 103;
}

void init2(){
	for (int i = 1; i <= 23; i ++)   yy[i] = i + 1;
}

int a[N], s[N];

signed main(){
	int T;
	scanf("%lld", &T);
	
	while(T --){
	
		int n, k;
		scanf("%lld%lld", &n, &k);
		
		int sum = 0;
		for (int i = 1; i <= n; i ++)   scanf("%lld", &a[i]);
		for (int i = 1; i < n; i ++)   sum += a[i];
		
		int ans = 0;
		for (int i = n; i >= 2; i --){
			int temp = (sum * k - a[i] * 100);
			temp = -temp;
			if (temp > 0){
				temp = (temp + k - 1) / k;
				ans += temp;
			    sum += temp;
			} 
			sum -= a[i - 1];	
		}
		
		printf("%lld\n", ans);
	
	}
	
	return 0;
}

C. Longest Simple Cycle
You have n chains, the i-th chain consists of ci vertices. Vertices in each chain are numbered independently from 1 to ci along the chain. In other words, the i-th chain is the undirected graph with ci vertices and (ci−1) edges connecting the j-th and the (j+1)-th vertices for each 1≤j<ci.

Now you decided to unite chains in one graph in the following way:

the first chain is skipped;
the 1-st vertex of the i-th chain is connected by an edge with the ai-th vertex of the (i−1)-th chain;
the last (ci-th) vertex of the i-th chain is connected by an edge with the bi-th vertex of the (i−1)-th chain.
Picture of the first test case. Dotted lines are the edges added during uniting process
Calculate the length of the longest simple cycle in the resulting graph.

A simple cycle is a chain where the first and last vertices are connected as well. If you travel along the simple cycle, each vertex of this cycle will be visited exactly once.

Input
The first line contains a single integer t (1≤t≤1000) — the number of test cases.

The first line of each test case contains the single integer n (2≤n≤105) — the number of chains you have.

The second line of each test case contains n integers c1,c2,…,cn (2≤ci≤109) — the number of vertices in the corresponding chains.

The third line of each test case contains n integers a1,a2,…,an (a1=−1; 1≤ai≤ci−1).

The fourth line of each test case contains n integers b1,b2,…,bn (b1=−1; 1≤bi≤ci−1).

Both a1 and b1 are equal to −1, they aren’t used in graph building and given just for index consistency. It’s guaranteed that the sum of n over all test cases doesn’t exceed 105.

Output
For each test case, print the length of the longest simple cycle.

Example
inputCopy
3
4
3 4 3 3
-1 1 2 2
-1 2 2 3
2
5 6
-1 5
-1 1
3
3 5 2
-1 1 1
-1 3 5
outputCopy
7
11
8
Note
In the first test case, the longest simple cycle is shown below:

We can’t increase it with the first chain, since in such case it won’t be simple — the vertex 2 on the second chain will break simplicity.

每个简单圆都有一个右边界,我们可以从 2 ~ n 枚举右边界 (1显然不能为右边界)
设 f[i] 为以第 i 条边为右边界的最大圆长度
当a[i] = b[i] 时 f[i] = c[i] - 1 + 2 (c[i] 是点数,c[i] - 1 才是边数)
否则 就有两种情况:

直接以第 i - 1 条线为左边界, 长度为: c[i] - 1 + 2 + abs(a[i] - b[i])
接在以第 i - 1 条线为右边界的圆后面,将 a[i] ~ b[i] 那一节线删去
则长度为: c[i] - 1 + 2 + f[i - 1] - abs(a[i] - b[i])
两种情况取最大就是 f[i] 的值
这边要注意初始化,f[1]为0,因为没有构成环

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
//#include <ext/rope>
#include <bits/stdc++.h> 

using namespace std;

#define gt(x) x = read()
#define int  long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
//#define x first
//#define y second

int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0}; 

typedef pair<double, int> PDI;
typedef pair<int, int> PII;
typedef unsigned long long ULL;

inline int read(int out = 0)
{
    char c;
    while((c=getchar()) < 48 || c > 57);
    while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
    return out; 
}

const int N = 1e5 + 10;
const int M = 4 * N;
const int mod = 1e4 + 7;
const int PP = 13331;
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const double PI = acos(-1);

int a[N], b[N], c[N], f[N];

signed main(){
	  int T;
	scanf("%lld", &T);
	while(T --)
	{
		int n;
		scanf("%lld", &n);
		for (int i = 1; i <= n; i ++)   scanf("%lld", &c[i]);
		for (int i = 1; i <= n; i ++)   scanf("%lld", &a[i]);
		for (int i = 1; i <= n; i ++)   scanf("%lld", &b[i]);
		
		int ans = 0;
		f[1] = 0;
		for (int i = 2; i <= n; i ++){
			if (b[i] == a[i])     f[i] = 1 + c[i];
			else{
				f[i] = max(c[i] + abs(b[i] - a[i]) - 1 + 2, f[i - 1] + c[i] - abs(a[i] - b[i]) - 1 + 2);
			}
			ans = max(ans, f[i]);
		}
		
		printf("%lld\n", ans);
	}
	
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 题目描述: 给定长度为 n 的数组 a1,a2,…,an,你需要判断它们能否被分成 k 段,使得每段的和都相等。 输入格式: 第一行包含两个整数 n 和 k。 第二行包含 n 个整数 a1,a2,…,an。 输出格式: 如果存在一种分段方案满足题目要求,输出 Yes,否则输出 No。 数据范围: 1≤n≤105, 1≤k≤105, 1≤ai≤104 样例: 输入: 5 3 1 2 3 4 5 输出: Yes 算法1 (贪心) $O(nlogn)$ 思路: 首先需要满足一定的条件,能被平分为k段,即数组总和能够被k整除。 然后我们可以尝试贪心的去划分这个数组,每次从数组中选择最大的数加入当前的段中,如果当前段的和已经达到了数组总和除以k,那么就可以开始下一段了。如果在遍历完整个数组之前无法划分为k段,那么说明无法满足题目要求,输出No。 C++ 代码 ### 回答2: A. Divisible Array (可整除数组)是指一个数组中的元素两两之间互相可整除。也就是说,对于数组中的任意两个元素a和b,必须满足a%b=0或b%a=0,其中%表示取余运算。 要判断一个数组是否是可整除数组,我们可以使用两层循环来遍历数组中的所有元素。对于每对元素a和b,判断a%b是否等于0或b%a是否等于0。如果存在一对元素a和b不满足这个条件,那么数组不是可整除数组;否则,数组是可整除数组。 以下是一个判断可整除数组的示例代码: ```python def is_divisible_array(arr): n = len(arr) for i in range(n): for j in range(i+1, n): if arr[i] % arr[j] != 0 and arr[j] % arr[i] != 0: return False return True ``` 以上代码中,我们使用两层循环来遍历数组中的所有元素对。如果存在一对元素不满足可整除的条件,我们立即返回False。如果循环结束后没有返回False,则说明数组是可整除数组,返回True。 总结:可整除数组是指一个数组中的元素两两之间互相可整除。通过遍历数组中的所有元素对,判断它们是否满足可整除的条件,即a%b=0或b%a=0,可以判断一个数组是否是可整除数组。以上是判断可整除数组的示例代码。 ### 回答3: Divisible Array(可被整除的数组)是一个数学问题,要求找到一个长度为n的数组,使得该数组中的所有元素两两之间都能整除。 首先需要明确的是,要使得一个数组中的所有元素两两之间都能整除,该数组中的最大公约数必须是所有元素的公约数,也就是说,最大公约数应该整除所有数组元素。 考虑到这一点,我们可以构造一个特殊的数组,数组中的每个元素都是n的倍数。这样,最大公约数就是n,n能整除数组中的所有元素,因此满足题目要求。 举个例子来说,如果要构造一个长度为6的可被整除的数组,我们可以选择n=6,然后数组中的元素可以为6、12、18、24、30、36,这样每个元素都能被6整除。 当然,这个问题的解并不唯一,我们也可以选择其他的n的倍数作为数组元素,只要最大公约数是n即可,例如n=12时,数组元素可以为12、24、36、48、60、72,同样满足题目要求。 综上所述,Divisible Array(可被整除的数组)可以通过构造数组中的每个元素都是n的倍数的方式来解决。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值