当前位置:主页 > 查看内容

Divide by Zero 2021 and Codeforces Round #714 (Div. 2) ABC

发布时间:2021-06-23 00:00| 位朋友查看

简介:A. Array and Peaks 题目大意寻找一个n的排列使得这个排列有k个峰值。 思路从i2每隔两个数放置一个当前没有放的最大值在放k个之后就停止如果不足k个就输出-1。接着继续从i1开始没有放置数字的位置接着放置当前没有放的最大值。 # include iostream # include……

A. Array and Peaks
题目大意:寻找一个n的排列,使得这个排列有k个峰值。

思路:从i=2每隔两个数放置一个当前没有放的最大值,在放k个之后就停止(如果不足k个就输出-1)。接着继续从i=1开始,没有放置数字的位置接着放置当前没有放的最大值。

#include <iostream>
#include <unordered_map>
#include <cstring>
using namespace std;
typedef long long ll;
unordered_map<int,ll> mp;
const int N = 110;
int a[N],vis[N];
int main()
{
    int t;cin>>t;
    while(t--)
    {
    	memset(a,0,sizeof a);
    	int n,k;cin>>n>>k;
		int cnt = n;
		int now = 0;
		for(int i=2;i<n&&k;i+=2)
			a[i] = cnt--,k--;
		if(k){
			puts("-1");
			continue;
		}
		for(int i=1;i<=n;i++)
			if(!a[i]) a[i] = cnt--;
		for(int i=1;i<=n;i++)
			cout<<a[i]<<" ";
		puts("");
	}
    return 0;
}

B. AND Sequences
给定一个数组a,询问a有多少种排列方式,使得每一个i,都有a1&a2&…&ai=ai+1&ai+2&…&an

思路:通过&的性质,发现这是一道排列组合题。
当时在做这道题时,注意到几个数字在一起&,结果只会越来越小。 于是就思考到找来a数组中的最小值,并且一头一尾放一个,中间的n-2个数字随便排 ; 记cnt为最小数字的个数,答案即为(cnt-1)*cnt*(n-2)!
然而很不幸的wa了,但是找最小值这个思路应该不会错吧。再次思考后发现,我们要寻找的“最小值”应该是a中所有数字&后的结果,这个结果如果在a中存在,那么就是最小值,如果不存在,就无解了。
代码:

#include <iostream>
#include <unordered_map>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long ll;
const ll N = 200010,mod = 1e9+7;
int a[N];
ll p[N];
int main()
{
	p[0] = p[1] = 1;
	for(int i=2;i<=200000;i++)
		p[i] = (p[i-1]*i)%mod;//预处理阶乘 
    int t;cin>>t;
    while(t--)
    {
		ll n;cin>>n;
		scanf("%d",&a[1]);
		int minn = a[1];
		for(int i=2;i<=n;i++)
		{
			scanf("%d",&a[i]);
			minn&=a[i];
		}
		ll cnt = 0;
		for(int i=1;i<=n;i++)
			if(a[i]==minn) cnt++;
		if(cnt<2)
		{
			puts("0");
			continue;
		}
		ll res = cnt*(cnt-1)%mod*p[n-2]%mod;
		printf("%lld\n",res);
	}
    return 0;
}

Add One
题目大意:给定一个数字n,进行m次操作,每次可以给n的每一位数字加1,求最后n的位数。

思路:这是一道dp问题。我们可以单独的考虑n的每一位数字在进行m次操作后的位数,最后累加即可。
又注意到,不同的数字(0~9)在进行m次累加后的结果是有关联的,因此我们直接定义dp数组f[i]为数字10进行了i次操作后的位数。 f[i] = f[i-9]+f[i-10] 初始化:f[0~8] = 2,f[9] = 3;
有了这个dp数组之后,我们就可以通过10 来计算出0~9的结果了
代码:

#include <iostream>
#include <unordered_map>
using namespace std;
typedef long long ll;
unordered_map<int,ll> mp;
const int N =200010,mod = 1e9+7;
int f[N];
void init()
{
	for(int i=0;i<=8;i++) f[i] = 2;
    f[9] = 3;
    for(int i=10;i<=200000;i++) f[i] = (f[i-9]+f[i-10])%mod;
}
int main()
{
	init();//初始化 
    int t;scanf("%d",&t);
    int n,m;
    while(t--)
    {	
		int res = 0;
    	int a[20],cnt = 0;
    	scanf("%d%d",&n,&m);
    	while(n) a[++cnt] = n%10,n/=10;
    	for(int i=1;i<=cnt;i++)
    		if(a[i]+m<10) res = (res+1)%mod;
    		else res = (res+f[m-(10-a[i])])%mod;
    	printf("%d\n",res);
	}
    return 0;
}

为什么没有D?因为菜

;原文链接:https://blog.csdn.net/qq_50748356/article/details/115620143
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐