19级算法训练赛第七场

A - 程序设计:合并数字

蒜头君得到了 nnn 个数,他想对这些数进行下面这样的操作,选出最左边的相邻的差的绝对值为 111 的两个数,只保留较小的数,删去较大的数,直到没有两个相邻的差的绝对值为 111 的数,问最多可以进行多少次这样的操作?
输入格式

输入第一行为一个整数 n(1≤n≤105)n(1 \leq n \leq 10^5)n(1≤n≤105),表示数字的总数
第二行为 nnn 个整数 x1,x2,…,xn(0≤xi≤109)x_1,x_2,…,x_n(0 \leq x_i \leq 10^9)x1​,x2​,…,xn​(0≤xi​≤109),表示这些数。
输出格式
输出一行,为一个整数,表示蒜头君最多可以进行多少次这样的操作。

样例输入

4
1 2 0 1

样例输出

3

这个题,我觉得我理解不了它的题意,还是我看着强哥的代码理解的题意

#include
#include
#include
using namespace std;
int main()
{
	stack<int> st;
	int n;int cnt=0;
	cin>>n;
	for(int i=0;i<n;i++) 
	{
		int x;
		cin>>x;
		while(1)
		{
			if(st.size()&&st.top()==x+1)
			{//如果此时栈不空,并且此时的栈顶大于输入的x,cnt就加一,并且将栈顶/
		//删掉,而此时的这个x还要与接下来的栈顶比较,            
				cnt++;
				st.pop();
				continue;
			}
			else if(st.size()&&st.top()==x-1)
			{//如果此时的栈顶要比输入的x要小,输入的x就不用进栈了直接cnt加一
				cnt++;
			}
			else st.push(x);//如果都不满足就将x直接进栈
			break;
		}
	}
	cout<<cnt<<endl;
	return 0;
}

B - 程序设计:找质数

一天蒜头君猜想,是不是所有的偶数(除了 222),都可以用两个质数相加得到呢?于是聪明的蒜头君就找你来验证了。
输入格式

第一行输入一个整数 ttt 表示测试组数。
接下来 ttt 行,每行一个整数 nnn。
输出格式
输出两个整数,因为答案可能有多个,所有要求输出的这两个整数是所有答案中字典序最小的。
数据范围
对于 30%30%30% 的数据 1≤t≤1031 \le t \le 10^31≤t≤103。
对于 60%60%60% 的数据 1≤t≤1051 \le t \le 10^51≤t≤105。
对于 100%100%100% 的数据 1≤t≤106,4≤n≤1061 \le t \le 10^6, 4 \le n \le 10^61≤t≤106,4≤n≤106,nnn 为偶数。
样例输入

3
4
8
20

样例输出

2 2
3 5
3 17

此处略去我对这个的题吐槽

#include
#include
using namespace std;
const int N=1e6+7;
bool st[N];
int primes[N], cnt;

void get_primes()
{
    for (int i = 2; i <= N; i ++ )
    {
        if (!st[i]) primes[cnt ++ ] = i;
        for (int j = 0; primes[j] <= N / i; j ++ )
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}

int main()
{
	get_primes();
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int x;
		scanf("%d",&x);
		for(int i=0;i<cnt;i++)
		{
			if(!st[x-primes[i]])
			{
				printf("%d %d\n",primes[i],x-primes[i]);
				break;
			}
			
		}
	}
	return 0;
}

C - Red and Black

There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can’t move on red tiles, he can move only on black tiles.

Write a program to count the number of black tiles which he can reach by repeating the moves described above.
Input
The input consists of multiple data sets. A data set starts with a line containing two positive integers W and H; W and H are the numbers of tiles in the x- and y- directions, respectively. W and H are not more than 20.

There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows.

‘.’ - a black tile
‘#’ - a red tile
‘@’ - a man on a black tile(appears exactly once in a data set)
Output
For each data set, your program should output a line which contains the number of tiles he can reach from the initial tile (including itself).
Sample Input

6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0

Sample Output

45
59
6
13

这个题要注意每次都要把st数组清空

#include
#include
#include
#include
using  namespace std;
typedef pair<int,int> pii;
char g[23][23];
bool st[23][23];
int dir[4][2]={1,0,0,1,0,-1,-1,0};
int bfs(int x,int y,int n,int m)
{
	memset(st,0,sizeof st);
	st[x][y]=1;
	int cnt=1;
	queue<pii> que;
	pii a;
	a.first=x;a.second=y;
	que.push(a);
	while(que.size())
	{
		a=que.front();
		que.pop();
		int x=a.first;int y=a.second;
		for(int i=0;i<4;i++)
		{
			int xx=x+dir[i][0];int yy=y+dir[i][1];
			if(xx>=0&&xx<n&&yy>=0&&yy<m&&!st[xx][yy]&&g[xx][yy]=='.')
			{
				st[xx][yy]=1;
				cnt++;
				que.push({xx,yy});
			}
		}
	}
	return  cnt;
}
int main()
{
	int n,m;
	int x,y;
	while(cin>>m>>n)
	{
		if(n==0&&m==0) break;
		memset(g,0,sizeof g);
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++) 
			{
				cin>>g[i][j];
				if(g[i][j]=='@') 
				{
					x=i;y=j;
				}
			}
		}
		cout<<bfs(x,y,n,m)<<endl;
	}
	return 0;
}

D - Game 23

Polycarp plays “Game 23”. Initially he has a number n and his goal is to transform it to m. In one move, he can multiply n by 2 or multiply n by 3. He can perform any number of moves.

Print the number of moves needed to transform n to m. Print -1 if it is impossible to do so.

It is easy to prove that any way to transform n to m contains the same number of moves (i.e. number of moves doesn’t depend on the way of transformation).
Input
The only line of the input contains two integers n and m (1≤n≤m≤5⋅108).
Output

Print the number of moves to transform n to m , or -1 if there is no solution.
Examples
Input

120 51840

Output

7

Input

42 42

Output

0

Input

48 72

Output

-1

Note

In the first example, the possible sequence of moves is: 120→240→720→1440→4320→12960→25920→51840.
The are 7 steps in total.
In the second example, no moves are needed. Thus, the answer is 0.
In the third example, it is impossible to transform 48 to 72.

#include
#include
using namespace std;
int main()
{
	int n,m;
	cin>>n>>m;
	int mn=m/n;
	if(n*mn!=m) cout<<"-1"<<endl;
	else
	{
		if(mn==1) cout<<"0"<<endl;
		else
		{
			int num=mn;
			int n2=0;int n3=0;
			while(mn%3==0)
			{
				n3++;
				mn/=3;
			}
			while(mn%2==0)
			{
				n2++;
				mn/=2;
			}
			if(pow(3,n3)*pow(2,n2)==num) cout<<n2+n3<<endl;
			else cout<<"-1"<<endl;
		}
	}
	return 0;
}

E - 棋盘问题

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
Sample Input

2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1

Sample Output

2
1

和八皇后有点类似,但是枚举完每一行之后要继续枚举下一行,是一个递归应用,其实递归还是不熟悉

#include
#include
#include
using namespace std;
char g[12][12];
int num,n,k,m;
bool st[12];
void dfs(int u)
{
	if(m==k) 
	{
		num++;
		return ;
	 } 
	 if(u>=n) return ;
	 for(int i=0;i<n;i++)
	 {
	 	if(st[i]==0&&g[u][i]=='#')
	 	{
	 		m++;
	 		st[i]=1;
	 		dfs(u+1);
	 		st[i]=0;
	 		m--;
		 }
	 }
	 dfs(u+1);
}
int main()
{
	while(cin>>n>>k)
	{
		if(n==-1&&k==-1) break;
	//	memset(g,0,sizeof g);
		memset(st,0,sizeof st);
		num=0;m=0;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++) cin>>g[i][j];
		}
		dfs(0);
		cout<<num<<endl;
	}
	
}

F - Super Jumping! Jumping! Jumping!

Nowadays, a kind of chess game called “Super Jumping! Jumping! Jumping!” is very popular in HDU. Maybe you are a good boy, and know little about this game, so I introduce it to you now.

在这里插入图片描述

The game can be played by two or more than two players. It consists of a chessboard(棋盘)and some chessmen(棋子), and all chessmen are marked by a positive integer or “start” or “end”. The player starts from start-point and must jumps into end-point finally. In the course of jumping, the player will visit the chessmen in the path, but everyone must jumps from one chessman to another absolutely bigger (you can assume start-point is a minimum and end-point is a maximum.). And all players cannot go backwards. One jumping can go from a chessman to next, also can go across many chessmen, and even you can straightly get to end-point from start-point. Of course you get zero point in this situation. A player is a winner if and only if he can get a bigger score according to his jumping solution. Note that your score comes from the sum of value on the chessmen in you jumping path.
Your task is to output the maximum value according to the given chessmen list.
Input
Input contains multiple test cases. Each test case is described in a line as follow: N value_1 value_2 …value_N
It is guarantied that N is not more than 1000 and all value_i are in the range of 32-int.
A test case starting with 0 terminates the input and this test case is not to be processed.
Output
For each case, print the maximum according to rules, and one line one case.
Sample Input

3 1 3 2
4 1 2 3 4
4 3 3 2 1
0

Sample Output

4
10
3

这个题附上强哥的代码,vector的话会默认每一个元素为0
而且数组里没有比他小的,那么它的dp就是他自己

#include
#include
#include
#include
using namespace std;
typedef long long ll;
int main()
{
	int n;
	while(cin>>n)
	{
		if(!n) break;
		vector<ll> arr(1010),dp(1010);
		for(int i=0;i<n;i++) cin>>arr[i];
		dp[0]=arr[0];
		for(int i=1;i<n;i++)
		{
			dp[i]=arr[i];
			for(int j=0;j<i;j++)
			{
				if(arr[i]>arr[j]) dp[i]=max(dp[j]+arr[i],dp[i]);
			}
		}
		long long ans=0;
		for(int i=0;i<n;i++) ans=max(dp[i],ans);
		cout<<ans<<endl;
	}
	return 0;
}

G - Primes

Write a program to read in a list of integers and determine whether or not each number is prime. A number, n, is prime if its only divisors are 1 and n. For this problem, the numbers 1 and 2 are not considered primes.
Input
Each input line contains a single integer. The list of integers is terminated with a number<= 0. You may assume that the input contains at most 250 numbers and each number is less than or equal to 16000.
Output
The output should consists of one line for every number, where each line first lists the problem number, followed by a colon and space, followed by “yes” or “no”.
Sample Input

1
2
3
4
5
17
0

Sample Output

1: no
2: no
3: yes
4: no
5: yes
6: yes
#include
#include
#include
using namespace std;
int main()
{
	int x;int cnt=0; 
	while(cin>>x)
	{
		if(x<=0) break;
		if(x==1||x==2) cout<<++cnt<<": no"<<endl;
		else 
		{
			int flag=1;
			for(int i=2;i<=x/i;i++)
			{
				if(x%i==0) 
				{
					flag=0;
					cout<<++cnt<<": no"<<endl;
					break;
				}
			}
			if(flag) cout<<++cnt<<": yes"<<endl;
		}
	}
	return 0;
}

H - WeirdSort

You are given an array a of length n.
You are also given a set of distinct positions p1,p2,…,pm, where 1≤pi For example, if a=[3,2,1]and p=[1,2], then we can first swap elements a[2] and a[3] (because position 2 is contained in the given set p). We get the array a=[3,1,2]. Then we swap a[1] and a[2] (position 1 is also contained in p). We get the array a=[1,3,2]. Finally, we swap a[2] and a[3] again and get the array a=[1,2,3], sorted in non-decreasing order.You can see that if a=[4,1,2,3]and p=[3,2] then you cannot sort the array.
You have to answer t independent test cases.
Input
The first line of the input contains one integer t(1≤t≤100) — the number of test cases.Then t test cases follow. The first line of each test case contains two integers n and m (1≤m Output
For each test case, print the answer — “YES” (without quotes) if you can sort the initial array in non-decreasing order (a1≤a2≤⋯≤an ) using only allowed swaps. Otherwise, print “NO”.
Example
Input

6
3 2
3 2 1
1 2
4 2
4 1 2 3
3 2
5 1
1 2 3 4 5
1
4 2
2 1 4 3
1 3
4 2
4 3 2 1
1 3
5 2
2 1 2 3 3
1 4

Output

YES
NO
YES
YES
NO
YES
#include
#include
#include
using namespace std;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int aa[123456];int p[123456];
		memset(aa,0x3f,sizeof aa);
		int n,m;
		cin>>n>>m;
		for(int i=1;i<=n;i++) cin>>aa[i];
		for(int i=1;i<=m;i++) cin>>p[i];
		sort(p+1,p+m+1);
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				if(aa[p[j]]>aa[p[j]+1]) swap(aa[p[j]],aa[p[j]+1]);
			}
		}
		int flag=1;
		for(int i=1;i<=n-1;i++)
		{
			if(aa[i]>aa[i+1]) 
			{
				flag=0;
				cout<<"NO"<<endl;
				break;
			}
		}
		if(flag) cout<<"YES"<<endl;
	}
	return 0;
}

I - Integer Divisibility

If an integer is not divisible by 2 or 5, some multiple of that number in decimal notation is a sequence of only a digit. Now you are given the number and the only allowable digit, you should report the number of digits of such multiple.

For example you have to find a multiple of 3 which contains only 1’s. Then the result is 3 because is 111 (3-digit) divisible by 3. Similarly if you are finding some multiple of 7 which contains only 3’s then, the result is 6, because 333333 is divisible by 7.
Input

Input starts with an integer T (≤ 300), denoting the number of test cases.

Each case will contain two integers n (0 < n ≤ 106 and n will not be divisible by 2 or 5) and the allowable digit (1 ≤ digit ≤ 9).
Output

For each case, print the case number and the number of digits of such multiple. If several solutions are there; report the minimum one.
Sample Input

3

3 1

7 3

9901 1

Sample Output

Case 1: 3

Case 2: 6

Case 3: 12

这个题主要应用了同余定理,主要体现在这一行while(x=x%n),x=x%n;这个是应用了同余定理

#include
#include
#include
#include
using namespace std;
int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);cout.tie(0);
	int t;
	scanf("%d",&t);
	for(int i=1;i<=t;i++)
	{
		long long n,m;long long cnt=1;
		scanf("%ld%ld",&n,&m);
		long long x=m;
		while(x=x%n)
		{
			cnt++;
			x=x*10+m;
		}
		printf("Case %d: %ld\n",i,cnt);
	//	cout<<"Case "<
	}
	return 0;
 } 

J - Pie

My birthday is coming up and traditionally I’m serving pie. Not just one pie, no, I have a number N of them, of various tastes and of various sizes. F of my friends are coming to my party and each of them gets a piece of pie. This should be one piece of one pie, not several small pieces since that looks messy. This piece can be one whole pie though.

My friends are very annoying and if one of them gets a bigger piece than the others, they start complaining. Therefore all of them should get equally sized (but not necessarily equally shaped) pieces, even if this leads to some pie getting spoiled (which is better than spoiling the party). Of course, I want a piece of pie for myself too, and that piece should also be of the same size.

What is the largest possible piece size all of us can get? All the pies are cylindrical in shape and they all have the same height 1, but the radii of the pies can be different.
Input
One line with a positive integer: the number of test cases. Then for each test case:
—One line with two integers N and F with 1 <= N, F <= 10 000: the number of pies and the number of friends.
—One line with N integers ri with 1 <= ri <= 10 000: the radii of the pies.
Output
For each test case, output one line with the largest possible volume V such that me and my friends can all get a pie piece of size V. The answer should be given as a floating point number with an absolute error of at most 10^(-3).
Sample Input

3
3 3
4 3 3
1 24
5
10 5
1 4 2 3 4 5 6 5 4 2

Sample Output

25.1327
3.1416
50.2655

附上强哥的教导:double乘上double会有精度损失,所以,可以用int读取r,而且枚举的是面积,不是半径

#include
#include
#include
#include
using namespace std;
const double pi=acos(-1.0);
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,m;
		double aa[12345];
		scanf("%d%d",&n,&m);
		m++;
		for(int i=0;i<n;i++) 
		{
			int R;
			scanf("%d",&R);
			aa[i]=R*R*pi;
		}
		sort(aa,aa+n);
		double l=0.0,r=aa[n-1];
		while(r-l>1e-6)
		{
			double mid=(l+r)/2;int cnt=0;
			for(int i=0;i<n;i++)  cnt+=(int)(aa[i]/mid);
			if(cnt<m) r=mid;
			else l=mid;
		}
		printf("%.4lf\n",l);
	}
	return 0;
}

K - 水果

夏天来了好开心啊,呵呵,好多好多水果
Joe经营着一个不大的水果店.他认为生存之道就是经营最受顾客欢迎的水果.现在他想要一份水果销售情况的明细表,这样Joe就可以很容易掌握所有水果的销售情况了.
Input
第一行正整数N(0 每组测试数据的第一行是一个整数M(0 Output
对于每一组测试数据,请你输出一份排版格式正确(请分析样本输出)的水果销售情况明细表.这份明细表包括所有水果的产地,名称和销售数目的信息.水果先按产地分类,产地按字母顺序排列;同一产地的水果按照名称排序,名称按字母顺序排序.
两组测试数据之间有一个空行.最后一组测试数据之后没有空行.
Sample Input

1
5
apple shandong 3
pineapple guangdong 1
sugarcane guangdong 1
pineapple guangdong 3
pineapple guangdong 1

Sample Output

guangdong
   |----pineapple(5)
   |----sugarcane(1)
shandong
   |----apple(3)

STL中map的应用,但是要注意遍历的时候的迭代器的使用

#include
#include
#include
using namespace std;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		map<string,map<string,int> > mp;
		int n;
		cin>>n;
		for(int i=0;i<n;i++)
		{
			string friut,area;int v;
			cin>>friut>>area>>v;
			mp[area][friut]+=v;
		}
		map<string,map<string,int> >::iterator it;
		map<string,int>::iterator it1;
		for(it=mp.begin();it!=mp.end();it++)
		{
			cout<<it->first<<endl;
			for(it1=(it->second).begin();it1!=(it->second).end();it1++)
			{
				cout<<"	  |----";
				cout<<it1->first<<"("<<it1->second<<")"<<endl;
			}
		}
		if(t) cout<<endl;
	}
	return 0;
}

L - Dead Pixel

Screen resolution of Polycarp’s monitor is a×b pixels. Unfortunately, there is one dead pixel at his screen. It has coordinates (x,y) (0≤x Polycarp wants to open a rectangular window of maximal size, which doesn’t contain the dead pixel. The boundaries of the window should be parallel to the sides of the screen.
Print the maximal area (in pixels) of a window that doesn’t contain the dead pixel inside itself.
Input

In the first line you are given an integer t (1≤t≤104) — the number of test cases in the test. In the next lines you are given descriptions of t test cases. Each test case contains a single line which consists of 4
integers a,b,x and y (1≤a,b≤104; 0≤x2 (e.g. a=b=1 is impossible).
Output

Print t integers — the answers for each test case. Each answer should contain an integer equal to the maximal possible area (in pixels) of a rectangular window, that doesn’t contain the dead pixel.
Example
Input

6
8 8 0 0
1 10 0 3
17 31 10 4
2 1 0 0
5 10 3 9
10 10 4 8

Output

56
6
442
1
45
80
#include
#include
using namespace std;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n,m,x,y;
		cin>>n>>m>>x>>y;
		x++;y++;
		long long l=n*(y-1);long long r=n*(m-y);
		long long u=m*(x-1);long long d=m*(n-x);
		cout<<max(max(max(l,r),u),d)<<endl;
	}
	return 0;
}

M - Complete the Sequence

You probably know those quizzes in Sunday magazines: given the sequence 1, 2, 3, 4, 5, what is the next number? Sometimes it is very easy to answer, sometimes it could be pretty hard. Because these “sequence problems” are very popular, ACM wants to implement them into the “Free Time” section of their new WAP portal.
ACM programmers have noticed that some of the quizzes can be solved by describing the sequence by polynomials. For example, the sequence 1, 2, 3, 4, 5 can be easily understood as a trivial polynomial. The next number is 6. But even more complex sequences, like 1, 2, 4, 7, 11, can be described by a polynomial. In this case, 1/2.n^2-1/2.n+1 can be used. Note that even if the members of the sequence are integers, polynomial coefficients may be any real numbers.
Polynomial is an expression in the following form:
P(n) = aD.nD+aD-1.nD-1+…+a1.n+a0 . If aD <> 0, the number D is called a degree of the polynomial. Note that constant function P(n) = C can be considered as polynomial of degree 0, and the zero function P(n) = 0 is usually defined to have degree -1.
Input
There is a single positive integer T on the first line of input. It stands for the number of test cases to follow. Each test case consists of two lines. First line of each test case contains two integer numbers S and C separated by a single space, 1 <= S < 100, 1 <= C < 100, (S+C) <= 100. The first number, S, stands for the length of the given sequence, the second number, C is the amount of numbers you are to find to complete the sequence.The second line of each test case contains S integer numbers X1, X2, … XS separated by a space. These numbers form the given sequence. The sequence can always be described by a polynomial P(n) such that for every i, Xi = P(i). Among these polynomials, we can find the polynomial Pmin with the lowest possible degree. This polynomial should be used for completing the sequence.
Output
For every test case, your program must print a single line containing C integer numbers, separated by a space. These numbers are the values completing the sequence according to the polynomial of the lowest possible degree. In other words, you are to print values Pmin(S+1), Pmin(S+2), … Pmin(S+C). It is guaranteed that the results Pmin(S+i) will be non-negative and will fit into the standard integer type.
Sample Input

4
6 3
1 2 3 4 5 6
8 2
1 2 4 7 11 16 22 29
10 2
1 1 1 1 1 1 1 1 1 2
1 10
3

Sample Output

7 8 9
37 46
11 56
3 3 3 3 3 3 3 3 3 3

这个是先给出多项式的前 n 项,然后找规律再输出 m 项,
其实对于这前n项,求n遍后一个数减去前一个数的操作之后就会只剩下一个数,然后再将这个数加 m 个,然后在进行逆运算,求前缀和求后m个数是多少

#include
#include
using namespace std;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int p[110][110];
		int n,m;
		cin>>n>>m;
		for(int i=0;i<n;i++) cin>>p[0][i];
		for(int i=1;i<n;i++)
		{
			for(int j=0;j+i<n;j++)
			{//依次进行差分,其实是一个倒三角
				p[i][j]=p[i-1][j+1]-p[i-1][j];
			}
		}
		for(int i=1;i<=m;i++) p[n-1][i]=p[n-1][0];
		for(int i=n-2;i>=0;i--)
		{//这是一个正三角,逆运算
			for(int j=n-i;j<n+m;j++)
			p[i][j]=p[i+1][j-1]+p[i][j-1];
		}
		for(int i=n;i<n+m-1;i++) cout<<p[0][i]<<" ";
		cout<<p[0][n+m-1]<<endl;
	}
	return 0;
}

N - Harmonic Number

In mathematics, the nth harmonic number is the sum of the reciprocals of the first n natural numbers:

19级算法训练赛第七场_第1张图片

In this problem, you are given n, you have to find Hn.
Input
Input starts with an integer T (≤ 10000), denoting the number of test cases.
Each case starts with a line containing an integer n (1 ≤ n ≤ 108).
Output
For each case, print the case number and the nth harmonic number. Errors less than 10-8 will be ignored.
Sample Input

12
1
2
3
4
5
6
7
8
9
90000000
99999999
100000000

Sample Output

Case 1: 1

Case 2: 1.5

Case 3: 1.8333333333

Case 4: 2.0833333333

Case 5: 2.2833333333

Case 6: 2.450

Case 7: 2.5928571429

Case 8: 2.7178571429

Case 9: 2.8289682540

Case 10: 18.8925358988

Case 11: 18.9978964039

Case 12: 18.9978964139

可以直接打表,十的八次方应该勉强是可以的,但是不能开一个1e8的数组,所以,可以开一个1e6的数组,每一百的数记录一下就行了,

#include
#include
#include
using namespace std;
const int N=1e8+9;
const int m=1e6+9;
double aa[m];
void init()
{
	double s=0;
	for(int i=1;i<=N;i++) 
	{
		s=s+1.0/i;
		if(i%100==0)	aa[i/100]=s;
	}
}
int main()
{
	init();
	int t;
	cin>>t;
	for(int i=1;i<=t;i++)
	{
		int x;
		cin>>x;
		int s=x/100;
		double ans=aa[s];
		for(int j=s*100+1;j<=x;j++) ans+= 1.0/j;
		printf("Case %d: %.10lf\n",i,ans);
	}
	return 0;
}

你可能感兴趣的:(19级算法训练赛第七场)