TopCoder SRM 569

div.1

T1

题意

有一台机器,给定两个长度为N的01串作为输入,分别对每一位进行与、或、异或中的一种操作,输出操作后的串。先给定M个01串,问至少要添加几个串,才能判断出机器对每一位分别进行什么操作。

思路

显然位与位之间互相独立,那么单独考虑一位。
对于每一位,都至少要有1个0,2个1,如果不足就要添加。
这是只有三种输入:(0,0),(0,1),(1,1)。能区别AND和OR的有(0,1);能区别AND和XOR的有(0,1)和(1,1);能区别OR和XOR的有(1,1)。只要分别统计M个串中每一位0和1的个数,再判断一下即可。答案不会超过2。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

class TheDevice {
public:
    int minimumAdditional( vector <string> plates );
};
int TheDevice::minimumAdditional(vector <string> a) {
	int n,m,ans,i,j,x,y,z;
	n=a.size();
	m=a[0].size();
	ans=0;
	for(j=0;j<m;j++)
	{
		x=0;
		y=0;
		z=0;
		for(i=0;i<n;i++)
			if(a[i][j]=='0') x++;
			else y++;
		if(x==0) z++;
		if(y<2) z=z+2-x;
		ans=max(ans,z);
	}
    return ans;
}
T2

题意

一栋大楼共N层(0~N-1),第i层有a[i]个人。每层都要分配a[i]/k取上整个城管来管这些人。第i层楼的人可以在第i层、i+1层或者i-1层中的某一层楼,求最少需要几个城管来管所有人。

思路

如果某一层的人数不是K的整数倍,那么我们可以将上下层多出的人移到该层。考虑第i-1、i和i+1层之间的关系。i-1->1和i+1->i可以视为i->i-1和i+1->i-1。假设只有i和i-1,那么双向的移动是等价的。三层楼之间互相影响只有上下两层都集中的一层这种情况(这和一层分散到两层是等价的),也与i+1->i-1等价。
那么就有这样一个贪心策略:从0层开始,计算0层需要几个城管,以及0层还能移入几个人,即为rem,然后从1层往0层移不超过rem的尽量多的人。如果此时移入的人还不超过rem(也即1层的人数少于rem),就从2层继续移。之后把1层视为新的0层,再重新开始。

#include <bits/stdc++.h>
using namespace std;
int n,c[100];

class TheJediTest {
public:
    int minimumSupervisors( vector <int> students, int K );
};
int sol(int x,int k)
{
	return x%k?x/k+1:x/k;
}
int TheJediTest::minimumSupervisors(vector <int> a, int k) {
    n=a.size();
    int ans=2e9,i,j,s,d,x;
    for(i=0;i<1<<(n-1);i++)
    {
    	s=0;
    	for(j=0;j<n;j++) c[j]=a[j];
    	for(j=0;j<n-1;j++)
    	{
    		d=c[j]%k;
    		if(i&(1<<j))
    		{
    			x=min(a[j],d);
    			c[j]=c[j]-x;
    			c[j+1]=c[j+1]+x;
    		}
    		else 
    		{
    			d=k-d;
    			if(d==k) d=0;
    			x=min(a[j+1],d);
    			c[j]=c[j]+x;
    			c[j+1]=c[j+1]-x;
    		}
    		s=s+sol(c[j],k);
    	}
    	s=s+sol(c[n-1],k);
    	ans=min(ans,s);
    }
    return ans;
}

div.2

T3

题意

n!k = n!(k-1) * (n-1)!k
0!k = 1
n!0 = n
求n!k

思路

可以直接根据题目给出的递推式把n!k个各个质因子个数递推出来(不过空间开不下要用滚动数组)
求因子个数有个公式相信大家小学就知道了
若x=p1a1⋅p2a2⋯pm^am,其中p1,p2,⋯,pm为质数
则x的因子个数为a1⋅a2⋯am
就相当于对每个质因子pi可以选[0,ai]次,共有ai+1种选法,根据乘法原理乘起来就行了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+9;
int vis[10010],p[10010],cnt;
ll d[2][1010][1010];

class MegaFactorialDiv2 {
public:
    int countDivisors( int N, int K );
};
int MegaFactorialDiv2::countDivisors(int n, int k) {
	int i,j,s=0,x,l;
	cnt=0;
	memset(d,0,sizeof(d));
	memset(vis,0,sizeof(vis));
	for(i=2;i<=1000;i++)
	{
		if(vis[i]==0) p[++cnt]=i;
		for(j=1;j<=cnt&&i*p[j]<=1000;j++)
		{
			vis[i*p[j]]=1;
			if(i%p[j]==0) break;
		}
	}
	for(i=1;i<=n;i++)
	{
		s=s^1;
		memset(d[s],0,sizeof(d[s]));
		x=i;
		for(j=1;j<=cnt;j++)
			while(x%p[j]==0)
			{
				x=x/p[j];
				d[s][0][j]++;
			}
		for(j=1;j<=k;j++)
			for(l=1;l<=cnt;l++)
				d[s][j][l]=(d[s^1][j][l]+d[s][j-1][l])%mod;
	}
    ll ans=1;
    for(i=1;i<=cnt;i++)
     ans=ans*(d[s][k][i]+1)%mod;
    return (int)ans%mod;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值