【比赛报告】 AHSOFNU codeforces训练赛2 by hzwer NOIP练习赛卷五

比赛链接

A.Stadium and Games

题目链接

Description

Daniel is organizing a football tournament. He has come up with the following tournament format:

In the first several (possibly zero) stages, while the number of teams is even, they split in pairs and play one game for each pair. At each stage the loser of each pair is eliminated (there are no draws). Such stages are held while the number of teams is even.
Eventually there will be an odd number of teams remaining. If there is one team remaining, it will be declared the winner, and the tournament ends. Otherwise each of the remaining teams will play with each other remaining team once in round robin tournament (if there are x teams, there will be games), and the tournament ends.
For example, if there were 20 teams initially, they would begin by playing 10 games. So, 10 teams would be eliminated, and the remaining 10 would play 5 games. Then the remaining 5 teams would play 10 games in a round robin tournament. In total there would be 10+5+10=25 games.

Daniel has already booked the stadium for n games. Help him to determine how many teams he should invite so that the tournament needs exactly n games. You should print all possible numbers of teams that will yield exactly n games in ascending order, or -1 if there are no such numbers.

Input

The first line contains a single integer n (1 ≤ n ≤ 1018), the number of games that should be played.

Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.

Output

Print all possible numbers of invited teams in ascending order, one per line. If exactly n games cannot be played, output one number: -1.

Examples

Input

3

Output

3
4

Input

25

Output

20

Input

2

Output

-1


设最后得到一个奇数 m m m ,最开始的人数为 2 p × m 2^p\times m 2p×m。则一共进行的比赛数 m × ( m − 1 ) 2 + ( 2 p − 1 ) × m = n \frac{m\times (m-1)}{2}+(2^p-1)\times m=n 2m×(m1)+(2p1)×m=n。此方程有两个未知量,可以枚举 p p p 二分查找 m m m

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const ll INF=15e8;
ll n;
int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n;
    bool find=false;ll c,i;
    for(i=0;(c=(1ll<<i)-1)<=n;i++)
    {
    	ll l=1,r=c?min(n/c+1,INF):INF,mid,cnt;
    	while(l<=r)
    	{
    		mid=(l+r)/2;
    		cnt=(mid-1)*mid/2+c*mid;
    		if(cnt==n)break;
    		else if(cnt<n)l=mid+1;
    		else r=mid-1;
		}
		cnt=(mid-1)*mid/2+c*mid;
		if(cnt==n&&mid%2==1)
		{
			cout<<(mid<<i)<<endl;
			find=true;
		}
	}
	if(!find)cout<<"-1"<<endl;
	return 0;
}

总结

通过枚举范围小的未知量来解方程。要注意二分的上下界,上限开大了会爆long long,开小了也会跪,开到 15 e 8 15e8 15e8 差不多。


B.LCM Challenge

题目链接

Description

Some days ago, I learned the concept of LCM (least common multiple). I’ve played with it for several times and I want to make a big number with it.

But I also don’t want to use many numbers, so I’ll choose three positive integers (they don’t have to be distinct) which are not greater than n. Can you help me to find the maximum possible least common multiple of these three integers?

Input

The first line contains an integer n (1 ≤ n ≤ 106) — the n mentioned in the statement.

Output

Print a single integer — the maximum possible LCM of three not necessarily distinct positive integers that are not greater than n.

Examples

Input

9

Output

504

Input

7

Output

210

Note

The least common multiple of some positive integers is the least positive integer which is multiple for each of them.

The result may become very large, 32-bit integer won’t be enough. So using 64-bit integers is recommended.

For the last example, we can chose numbers 7, 6, 5 and the LCM of them is 7·6·5 = 210. It is the maximum value we can get.


大佬的解法非常巧妙,摘抄如下:
题目大意:求不超过n的三个数的最大公倍数。
分析:首先要知道两个数论性质:1、相邻两个整数互质。2、相邻两个奇数互质。
然后,小数据观察规律,按 n n n 的奇偶性讨论。
一、 n n n 为奇数时, n − 2 n-2 n2 必定为奇数,而 n − 1 n-1 n1 与它俩都相邻,因此,两两互质。最大公倍数即为 n ∗ ( n − 1 ) ∗ ( n − 2 ) n*(n-1)*(n-2) n(n1)(n2)
二、 n n n 为偶数时,由于 n n n n − 2 n-2 n2 均为偶数,所以,退而求其次,选择 n − 3 n-3 n3 。又 n n n n − 3 n-3 n3 是否互质,衍生出两种情况:
1、 n n n 3 3 3 的倍数,则 n n n n − 3 n-3 n3 不互质,然而, n n n n − 4 n-4 n4 不互质,所以,此时,不选择 n n n,改为选 n − 2 n-2 n2。最后, L C M = ( n − 1 ) ∗ ( n − 2 ) ∗ ( n − 3 ) LCM = (n-1)*(n-2)*(n-3) LCM=(n1)(n2)(n3)
2、 n n n不为 3 3 3 的倍数,则 n n n n − 3 n-3 n3 互质,所以, L C M = n ∗ ( n − 1 ) ∗ ( n − 3 ) LCM = n*(n-1)*(n-3) LCM=n(n1)(n3)

#include<cstdio>
typedef long long ll;
int main()
{
	ll n;
	scanf("%lld",&n);
	if(n==1)puts("1");
	else if(n==2)puts("2");
	else if(n&1)printf("%lld\n",n*(n-1)*(n-2));
	else if(n%3==0)printf("%lld\n",(n-1)*(n-2)*(n-3));
	else printf("%lld\n",n*(n-1)*(n-3));
	return 0;
}

总结

数学是一生之敌。巧妙利用互质的性质。


C.Weird Game

题目链接

Description

Yaroslav, Andrey and Roman can play cubes for hours and hours. But the game is for three, so when Roman doesn’t show up, Yaroslav and Andrey play another game.

Roman leaves a word for each of them. Each word consists of 2·n binary characters “0” or “1”. After that the players start moving in turns. Yaroslav moves first. During a move, a player must choose an integer from 1 to 2·n, which hasn’t been chosen by anybody up to that moment. Then the player takes a piece of paper and writes out the corresponding character from his string.

Let’s represent Yaroslav’s word as s = s1s2… s2n. Similarly, let’s represent Andrey’s word as t = t1t2… t2n. Then, if Yaroslav choose number k during his move, then he is going to write out character sk on the piece of paper. Similarly, if Andrey choose number r during his move, then he is going to write out character tr on the piece of paper.

The game finishes when no player can make a move. After the game is over, Yaroslav makes some integer from the characters written on his piece of paper (Yaroslav can arrange these characters as he wants). Andrey does the same. The resulting numbers can contain leading zeroes. The person with the largest number wins. If the numbers are equal, the game ends with a draw.

You are given two strings s and t. Determine the outcome of the game provided that Yaroslav and Andrey play optimally well.

Input

The first line contains integer n (1 ≤ n ≤ 106). The second line contains string s — Yaroslav’s word. The third line contains string t — Andrey’s word.

It is guaranteed that both words consist of 2·n characters “0” and “1”.

Output

Print “First”, if both players play optimally well and Yaroslav wins. If Andrey wins, print “Second” and if the game ends with a draw, print “Draw”. Print the words without the quotes.

Examples

Input

2
0111
0001

Output

First

Input

3
110110
001001

Output

First

Input

3
111000
000111

Output

Draw

Input

4
01010110
00101101

Output

First

Input

4
01100000
10010011

Output

Second


优先选择双方都为1的,次选己方为1,次选对方为1。

#include<cstdio>
#include<iostream>
using namespace std;
string s,t;
int n,cnts,cntt,cntd;
int main()
{
	//freopen("in.txt","r",stdin);
    cin>>n;n*=2;
    cin>>s>>t;
    for(int i=0;i<n;i++)
    {
    	if(s[i]=='1'&&t[i]=='1')cntd++;
    	else if(s[i]=='1')cnts++;
    	else if(t[i]=='1')cntt++;
	}
	cntd%=2;cnts+=cntd;if(cnts+1==cntt)cntt--;
	if(cnts>cntt)puts("First");
	else if(cnts<cntt)puts("Second");
	else puts("Draw");
	return 0;
}

总结

博弈论初步


D.Distinct Paths

题目链接

Description

You have a rectangular n × m-cell board. Some cells are already painted some of k colors. You need to paint each uncolored cell one of the k colors so that any path from the upper left square to the lower right one doesn’t contain any two cells of the same color. The path can go only along side-adjacent cells and can only go down or right.

Print the number of possible paintings modulo 1000000007 (109 + 7).

Input

The first line contains three integers n, m, k (1 ≤ n, m ≤ 1000, 1 ≤ k ≤ 10). The next n lines contain m integers each — the board. The first of them contains m uppermost cells of the board from the left to the right and the second one contains m cells from the second uppermost row and so on. If a number in a line equals 0, then the corresponding cell isn’t painted. Otherwise, this number represents the initial color of the board cell — an integer from 1 to k.

Consider all colors numbered from 1 to k in some manner.

Output

Print the number of possible paintings modulo 1000000007 (109 + 7).

Examples

Input

2 2 4
0 0
0 0

Output

48

Input

2 2 4
1 2
2 1

Output

0

Input

5 6 10
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0

Output

3628800

Input

2 6 10
1 2 3 4 5 6
0 0 0 0 0 0

Output

4096


大佬题解写的非常好,摘抄如下:

题目大意:
给出一个n*m的矩阵,其中一些格子填了数,一些格子没有。现要求将未填数的格子填上数字,使得矩阵从左上到右下(不允许向左或上走)的任意一条路径上没有两个格子数字相同,数字范围为1~K。 1<=n,m<=1000,1<=k<=10
分析:
首先一看,在(n+m-1)大于K时必定无解,这样就把n,m范围缩小到了10以内。
我们考虑搜索解决。但是纯暴搜时间不够,可以用两个剪枝优化:
(1)可行性剪枝,如果在当前格子填数时,剩下的颜色已经不够用则直接回溯。
(2)对称性剪枝:例如我们当前填到了某个格子,我们记录一下整个矩阵已使用的颜色,例如3,5都还没用,那么这个格子填上3或5,两者最终算出的方案数是相同的,这样我们就可以只计算3的方案数,5的直接加上3的就可以了。

#include<cstdio>
typedef long long ll;
const int mod=1e9+7;
int n,m,k,vis[11],a[11][11],f[11][11];//f[x][y]记录每个阶段颜色的使用情况 
ll ans;
void dfs(int x,int y)
{
	if(x==n+1)
	{
		if(++ans==mod)ans=0;
		return;
	}
	f[x][y]=f[x-1][y]|f[x][y-1];
	int cnt=0,p=1,q=k;ll sum=-1,pre;
	for(int i=1;i<=k;i++)if((f[x][y]&(1<<(i-1)))!=0)cnt++;//已用颜色数
	if(n-x+m-y+1>k-cnt)return;//可行性剪枝 
	if(a[x][y]>0)p=q=a[x][y];
	for(int i=p;i<=q;i++)
	    if((f[x][y]&(1<<(i-1)))==0)//当前状态没用过这种颜色 
	    {
	    	if(!vis[i])//这个颜色没出现过 
	    	{
	    		if(sum>=0)//对称性剪枝,如果sum>=0说明该位的颜色是没出现过的,且已经考虑过 
	    		{
	    			ans+=sum;
	    			if(ans>=mod)ans-=mod;
	    			continue;
				}
				pre=ans;
			}
			f[x][y]^=(1<<(i-1)),vis[i]++;
			if(y==m)dfs(x+1,1);else dfs(x,y+1);
			f[x][y]^=(1<<(i-1)),vis[i]--;
			if(!vis[i])sum=(ans-pre)%mod;//对于没用过的颜色,得到的sum是相等的 
		}
}
int main()
{
	//freopen("in.txt","r",stdin);;
    scanf("%d%d%d",&n,&m,&k);
    if(n+m-1>k)
    {
    	puts("0");return 0;
	}
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=m;j++)
	    {
	    	scanf("%d",&a[i][j]);
	    	if(a[i][j]>0)vis[a[i][j]]++;//记录颜色出现数 
		}
	dfs(1,1);
	printf("%lld\n",ans);
	return 0;
}

总结

果然爆搜才是男人的浪漫。


比赛总结

其实也不算比赛,就只是做练习题。考的还是一些算法难度不大但比较考思维的东东,不错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值