Codeforces Round #451 (Div. 2) [ D. Alarm Clock ] [ E. Squares and not squares ] [ F. Restoring the Expression ]

PROBLEM D. Alarm Clock

  OvO http://codeforces.com/contest/898/problem/D

  codeforces 898d

  从前往后枚举,放进去后不合法就拿出来,记录拿出来的次数

  中途每放进去一个数,会影响到一个区间,标记这个区间的首位(做差分,首+1,尾-1),同时维护这些标记的前缀和

#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdio>

using namespace std;

const int M=1e6+44;

int n,m,k;
int s[M];
int sum[M],num[M];

int main()
{
	int lst,ans=0;
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=n;i++)
		scanf("%d",&s[i]);
	sort(s+1,s+n+1);	
	memset(sum,0,sizeof(sum));
	lst=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=lst+1;j<=s[i];j++)
			sum[j]+=sum[j-1];
		lst=s[i];
		if(sum[s[i]]-sum[max(0,s[i]-m)]+1>=k)
			ans++;
		else
			sum[s[i]]++;
	}
	printf("%d\n",ans);
	return 0;
}

  

PROBLEM E. Squares and not squares 

题 

  OvO http://codeforces.com/contest/898/problem/E

  codeforces 898e

  预处理出10000个左右的完全平方数,然后对于每个输入的数归类他们是否是完全平方数,并且算出各自的最小代价(二分之类的)

  然后根据代价排序,从小到大补足

#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <set>

using namespace std;

typedef long long ll;

const ll M=2e5+44;

struct Node
{
	ll num,val;
} g[M],ng[M];

ll lg,lng;
ll n,m;
ll s[M];
ll p[M];
ll lp;
set<ll> se;

bool cmp(Node a,Node b)
{
	return a.val<b.val;
}

void init()
{
	se.clear();
	lp=100000;
	for(ll i=0;i<=lp;i++)
		p[i]=1ll*i*i,se.insert(p[i]);
}

int main()
{
	ll tmp,ans;
	init();
	scanf("%I64d",&n);
	lg=lng=0;
	for(ll i=1;i<=n;i++)
	{
		scanf("%I64d",&s[i]);
		if(se.find(s[i])==se.end())
		{
			ng[++lng].num=s[i];
			tmp=upper_bound(p,p+lp+1,s[i])-p;
			ng[lng].val=min(p[tmp]-s[i],s[i]-p[tmp-1]);
		}
		else
		{
			g[++lg].num=s[i];
			if(s[i]==0) g[lg].val=2;
			else g[lg].val=1;
		}
	}
	sort(ng+1,ng+lng+1,cmp);
	sort(g+1,g+lg+1,cmp);
	m=n/2;
	ans=0;
	if(lng>m)
	{
		for(ll i=1;i<=lng-m;i++)
			ans+=ng[i].val;
	}
	else
	{
		for(ll i=1;i<=lg-m;i++)
			ans+=g[i].val;
	}
	printf("%I64d\n",ans);
	return 0;
}

  

  

  

PROBLEM F. Restoring the Expression

  OvO http://codeforces.com/contest/898/problem/F

  codeforces 898f

  记三段为A,B,C,枚举C段的长度lc,分别判断la=lc-1,la=lc,lb=lc-1,lb=lc,这4种情况是否合法。

  判断的话,做个哈希差不多的东西用来判断加法结果是否正确(哈希sed=10),截断的部分会涉及到除法,用逆元处理。哈希判断正确之后真实值再判断一次

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>

using namespace std;

const int M=1e6+44;
const int sed=10; 
const int mod=1e9+7;

int n;
char str[M];
int s[M];
int suf[M];
int bas[M],inv[M];

long long pr(int a, int b)
{
    long long r=1,base=a;
    while(b!=0)
    {
        if(b&1)
            r=(r*base)%mod;
        base=(base*base)%mod;
        b>>=1;
    }
    return r;
}

bool check(int la,int lb,int lc)
{
	int sava=la,savb=lb,savc=lc;
	if(la>lc || lb>lc || la<1 || lb<1 || lc<1) return false;
	int lia=1,lib=la+1,lic=la+lb+1;
	if((la>1 && s[lia]==0) || (lb>1 && s[lib]==0) || (lc>1 && s[lic]==0)) return false;
	int ria=la,rib=la+lb,ric=la+lb+lc;
	int vala,valb,valc,up=0,tmp;
	while(lc>0)
	{
		if(la>0) vala=s[ria];
		else vala=0;
		if(lb>0) valb=s[rib];
		else valb=0;
		tmp=up+vala+valb;
		up=tmp/10; tmp%=10;
		if(tmp!=s[ric])
			return false;
		la--; lb--; lc--;
		ria--; rib--; ric--;
	}
	if(up) return false;
	for(int i=1;i<=n;i++)
	{
		printf("%d",s[i]);
		if(i==sava) printf("+");
		if(i==sava+savb) printf("=");
	}
	return true;
}

int getval(int li,int ri)
{
	int ret,tmp;
	tmp=(0ll+suf[li]-suf[ri+1])%mod;
	tmp=(1ll*tmp*inv[n-ri])%mod;
	ret=(tmp%mod+mod)%mod;
	return ret;
}

bool solve(int la,int lb,int lc)
{
	int sava=la,savb=lb,savc=lc;
	if(la>lc || lb>lc || la<1 || lb<1 || lc<1) return false;
	int lia=1,lib=la+1,lic=la+lb+1;
	if((la>1 && s[lia]==0) || (lb>1 && s[lib]==0) || (lc>1 && s[lic]==0)) return false;
	int ria=la,rib=la+lb,ric=la+lb+lc;
	int vala,valb,valc;
	vala=getval(lia,ria);
	valb=getval(lib,rib);
	valc=getval(lic,ric);
//	cout<<la<<' '<<lb<<' '<<lc<<endl;
//	cout<<vala<<' '<<valb<<' '<<valc%mod<<endl;
	if((0ll+vala+valb)%mod==valc%mod && check(la,lb,lc))
		return true;
	else return false;
}

int main()
{
	scanf("%s",str+1);
	n=strlen(str+1);
	for(int i=1;i<=n;i++)
		s[i]=str[i]-'0';
	bas[0]=1;
	for(int i=1;i<=n;i++)
		bas[i]=1ll*bas[i-1]*sed%mod;
	for(int i=0;i<=n;i++)
		inv[i]=pr(bas[i],mod-2);
	suf[n+1]=0;
	for(int i=n;i>=1;i--)
		suf[i]=(suf[i+1]+1ll*bas[n-i]*s[i]%mod)%mod;
	for(int i=1;i<=n;i++)
	{
		if(solve(i-1,n-i-(i-1),i) || solve(i,n-i-i,i) || solve(n-i-(i-1),i-1,i) || solve(n-i-i,i,i))
			return 0;
	}
	return 0;
}

  

 

posted @ 2017-12-17 00:13  太阳星人FxxL  阅读(526)  评论(0编辑  收藏  举报