SDUT 2021 Spring Individual Contest(for 20) - 12(补题)

Ran and the Lock Code

Two days ago, a woman called Fumiyo Edogawa knocked the door of Kogoro Mouri home and claimed that she is Conan’s mom. Fumiyo introduced herself as Conan’s mother and used fake documents to prove this. Conan, Kogoro Mouri, and his daughter Ran believed her. So, Conan went with her.

Ran was worried about Conan. After investigations, Ran discovered that Conan has been kidnapped! Ran called the police and they helped her to find Conan’s location. When they arrived at that location, Ran shocked because she discovered that Conan is detained inside a locked coffin.

After examining the coffin, Ran discovered that it is locked using a modern electronic lock. Ran can open the lock only by solving T mysteries. In each mystery, Ran is giving two numbers n and a, and she needs to find the maximum number of distinct elements that can exist in a list of n positive elements with an average equals to a.

Ran knows that time is running out of her, and she must expedite in solving the mysteries to get Conan out of the coffin before his breath stopped. Ran asked you to help her in solving the mysteries. Will you leave Conan to die smothered or will you help Ran solving the mysteries?
Input

The first line contains an integer T (1 ≤ T ≤ 105), in which T is the number of mysteries.

Then T lines follow, giving the mysteries. Each line contains two integers n and a (1 ≤ n, a ≤ 109), in which n is the number of elements in the list, and a is the required average of that list.
Output

For each test case, print a single line containing the maximum number of distinct elements that can exist in a list of n positive elements with an average equals to a.
Example
Input

3
2 4
5 1
8 4
Output
2
1
7
Note
The average of a list of n elements x1, x2, …, xn is defined as the ratio between the sum of the n elements and n. More formally:
In the first test case, Ran is asked to find the maximum number of distinct elements that can exist in a list of 2 positive elements with an average equals to 4. Ran can choose a list such as [3, 5]. So, the number of distinct elements is 2.
题意: n个数的平均值是a,求n个数的组成中,最多有多少个不同的数
思路: n个数的和就是sum=na,假如有x个数不同,即这些数是1.2.3.4…x(x>=1) ,前面这些数的和就是sum1=x(x-1)/2,那么剩下n-x数的和就是sum2=sum-x*(x-1)/2, 因为所有的数>=1sum2>=sum1,所以展开不等式,就是 n ∗ a > = x ∗ ( x − 1 ) / 2 + ( n − x ) n*a>=x*(x-1)/2+(n-x) n∗a>=x∗(x−1)/2+(n−x) 仔细想想的话,这个式子的含义(个人理解 ),就是这n个数的和一定>=前x个数的和+后n-x的个数,因为后n-x的个数<=后n-x的和(当且仅当后n-x的数全为1时,等号成立),所以不等式成立。求这x是多少,就要利用二分,从1—n利用二分找出符合不等式中最大的x。

利用二分找出不等式中的最大的那个x值,一定是正确的,因为不等式的推导就是根据题目要求本身推的。

怎么想的: 下面再浅谈一下,为何有这个思路(毕竟,不光要知其然,还要知其所以然)。很多人刚看到这个题的时候,估计可能脑内浮现的可能是,列出n个a,从中间开始,对左边的a分别-1,-2…在对左边的数分别+1,+2这样就平均数依然是a。(这也是我一开始天真的想法)

但是如果此时n=8,a=3(举个例子,像这样的情况有很多)。如果按照错误思路,就会形成1,2,3,3,3,3,4,5.这5个结果。错误思想无法想到2a,1,a-1,这种搭配模式。但实际上可以写1,1,2,2,3,4,5,6这6种不同的数字,导致结果不同的原因就是n(n+1)/x与nm两个数据的偏差导致的。

旧思想仅适用于有1—n,n个数,前n个数的和n(n+1)/2<=n* m的时候。如果前n个数(从小到大)的和,比n*m还小(或者等于)那就说明仅用n个不同的数就能表达出这个平均数。

但如果n(n+1)/2>n*m,这样如果还让n个数从1一直到n的话,那样前n个数的和,就不满足题目要求了。就需要利用不等式找出最大的数来。

下面代码的每一步判断都可以从我上面的描述中找到,所以就不写注释了。

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
int t;
ll n,m;
ll check(ll n,ll all){
	ll mid=-1,l=1,r=n;
	while(l<r){
		mid=(l+r)/2+1;
		if((mid+1)*mid/2+(n-mid)>all) r=mid-1;
		else l=mid;
	}
	return l;
}
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%lld%lld",&n,&m);
		if(m==1) printf("1\n");
		else if((1+n)*n/2<=n*m){
			printf("%lld\n",n);
		}
		else {
			ll x=check(n,n*m);
			printf("%lld\n",x);
		}
	}
	return 0;
}

Preparing for Exams

Ran Mouri and Sonoko Suzuki are preparing for the final exams. They decided to study mathematics as it is the hardest subject for them. While they are solving mathematical problems, they faced troubles with some questions, including the following question:

You are given a drawing for a sensor and some measurements about it. You have to find the rest of measurements. Sensor’s design is as follow:
SDUT 2021 Spring Individual Contest(for 20) - 12(补题)

The data you have is the length of , the length of , the area of oda, and the area of obc. Your task is to calculate x and y, where x is the length of and y is the length of .

Can you help Ran and Sonoko Suzuki by solving this question?
Input

The first line contains an integer T (1 ≤ T ≤ 2 × 105), in which T is the number of test cases.

Then T lines follow, each line contains four integers k, l, m, and n (1 ≤ k, l, m, n ≤ 1012), in which k is the length of , l is the length of , m is the area of oda, and n is the area of obc.
Output

For each test case, print a single line containing two numbers x and y, where x is the length of and y is the length of . Your output will be considered correct if the absolute or relative error of every number in your output does not exceed 10 - 6.
Example
Input

1
18 16 72 288
Output
20 14
题意: 就是一道几何数学题,算出x和y的值即可。
思路: 要用到的定理或公式,1.圆内四边形内角互补,2.三角形面积公式S=1/2absinc。关键就是证明相似,1.角o都相等 2.证明角oda等于角obc。(角oda+角adc=180.角adc+角abc等于180(圆的性质,对顶角相加等于180,)
证明完毕。利用三角形面积公式,求出sino,在用一次这个公式求出oc
ob,再利用oc/oa=ob/od,即可求出答案。
下面的代码省略了中间过程,直接求的答案。(唯一要注意的点,就是最后输出答案的精度问题)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
double a,d,s1,s2;
int main()
{
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%lf%lf%lf%lf",&a,&d,&s1,&s2);
		double sin=2*s1/(a*d);
		double dex=sqrt((2*s2*a)/(d*sin));
		double x=dex-d;
		double y=(d+x)*d/a-a;
		printf("%.8lf %8lf\n",x,y);
	}
	return 0;
}

Genta Game

Kojima Genta is one of the best friends of Conan, and the fattest one!

Everyone believes that Genta is just thinking about food. So, he wants to prove the opposite. So, his friends challenged him in a game. Genta’s friends will give him a string s of length n, and m update operations. At each update operation, an integer p (1 ≤ p ≤ n) and a lowercase English letter c will be given to Genta, and he is asked to change the pth letter in the string s to the letter c.

Conan explained to Genta that an update operation is said to be beautiful if the string s was a palindrome string after the update operation has been executed.

Genta task is to count the number of beautiful update operations. Genta wants to win in this game no matter what this will cost because his friends promised him that the food will be at their expense throughout the week if he solved the task. Can you help Genta by solving his task?
Input

The first line contains an integer T (1 ≤ T ≤ 50), in which T is the number of test cases.

The first line of each test cases contains two integers n and m (1 ≤ n, m ≤ 105), in which n is the length of the string s and m is the number of update operations. The second line of each test cases contains a string s of length n consisting of lowercase English letters only. Then m lines follow, each line contains an integer p and a lowercase English letter c (1 ≤ p ≤ n), giving the update operations.

The sum of n and m overall test cases does not exceed 7 × 105 for each.
Output

For each test case, print a single line containing the number of beautiful update operations.

Example
Input

1
10 7
abcdefdcba
5 x
6 x
4 d
2 d
3 y
8 y
9 d

Output
3

Note

A palindrome is a word, phrase, number, or other sequence of characters which reads the same backward as forward, such as “madam” or “racecar”.

In the first test case, the string s will be updated as follow:

abcdefdcba abcdxfdcba abcdxxdcba abcdxxdcba adcdxxdcba adydxxdcba adydxxdyba adydxxdyda.

There are 3 beautiful update operations, which are the 2rd, 3th, and 7th operations.
题意: 给个字符串,对它进行m次操作,问有总共有多少次操作使字符串使回文字符串。
思路: 一开始用sum记录字符串种有几组对称的单字符,每进行一次操作,就判断对应位置(其他位置已经用预处理过),如果原来是不对称改后变成对称的,个数sum+1。
如果原来是对称的,改后变成非对称的,个数sum-1。
其他情况,sum不变化。,如果sum的值==n/2的个数,说明是回文字符串,记录这个操作+1。
下面展示一些 内联代码片

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+7;
string s;
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
		int n,m;
		cin>>n>>m;
		cin>>s;
		char op;
		int x;
		int sum=0;
		for(int i=0;i<n/2;i++){
			if(s[i]==s[n-i-1])
			{
				sum++;
			}
		}
		int con=0;
		while(m--){
			scanf("%d",&x);
			   if(s[x-1]==s[n-x])
			   {
				  cin>>op;
		     	  s[x-1]=op;
		     	  if(s[x-1]!=s[n-x]) sum--; 
			   }
			   else if(s[x-1]!=s[n-x])
			    {
				   cin>>op;
		     	   s[x-1]=op;
					if(s[x-1]==s[n-x]) sum++; 
			    }
			}
			if(sum==n/2) con++;
		}
		printf("%d\n",con);
	}
	return 0;
}

To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激

上一篇:C++包管理器


下一篇:Python_学习之多协程