[ABC195] Panasonic Programming Contest (AtCoder Beginner Contest 195)

Tasks


Task Name Time Limit Memory Limit
A Health M Death 2 sec 1024 MB Submit
B Many Oranges 2 sec 1024 MB Submit
C Comma 2 sec 1024 MB Submit
D Shipping Center 2 sec 1024 MB Submit
E Lucky 7 Battle 2 sec 1024 MB Submit
F Coprime Present 2 sec 1024 MB Submit

A Health M Death

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

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;

int main()
{
//	freopen("1.in","r",stdin);
	int n,m;
	cin>>n>>m;
	if(m%n==0) puts("Yes");
	else puts("No");
	return 0;
}

B Many Oranges

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

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;

LL A,B,W;

int main()
{
//	freopen("1.in","r",stdin);
	cin>>A>>B>>W;
	W*=1000;
	LL ans=W/B;
	while(ans*B<W) ans++;
	if(A*ans>W) puts("UNSATISFIABLE");
	else {
		printf("%lld ",ans);
		ans=W/A;
		while((ans+1)*A<=W) ans++;
		printf("%lld\n",ans);
	}
	return 0;
}

C Comma

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

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;

// a num of x bit will use (x-1)/3 ","

LL n,ans;
int main()
{
//	freopen("1.in","r",stdin);
	cin>>n;
	LL bits=1,total=9;
	while(n>=total) {
		ans+=(bits-1)/3*total;
		n-=total;
		bits++;
		total*=10;
	}
	ans+=(bits-1)/3*n;
	cout<<ans<<endl;
	return 0;
}

D Shipping Center

整个人都费用流了。

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

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;

const int N=512,M=1e6+5;
const LL INF=0x3f3f3f3f3f3f3f3f;

int one[N],idx;
int ver[M],Next[M];
LL edge[M],w[M];
inline void AddEdge(int a,int b,LL c,LL d)
{
	Next[idx]=one[a]; ver[idx]=b; edge[idx]=c; w[idx]=d; one[a]=idx++;
	Next[idx]=one[b]; ver[idx]=a; edge[idx]=0; w[idx]=-d; one[b]=idx++;
}

int n,m,S,T,Q;

LL dis[N];
int cur[N];
bool vis[N];
queue<int> q;

bool spfa()
{
	memset(dis,-0x3f,sizeof dis);
	memset(vis,0,sizeof vis);
	memcpy(cur,one,sizeof cur);
	while(q.size()) q.pop();
	
	int i,x,y;
	q.push(S); dis[S]=0;
	while(q.size()) {
		x=q.front(); q.pop();
		vis[x]=false;
		for(i=one[x];~i;i=Next[i]) 
			if(edge[i] && dis[y=ver[i]]<dis[x]+w[i]) {
				dis[y]=dis[x]+w[i];
				if(!vis[y]) q.push(y),vis[y]=true;
			}
	}
	return dis[T]>-INF/2;
}

LL ans;
LL mcmf(int x,LL limit)
{
	if(x==T) return limit;
	vis[x]=true;
	LL k,flow=0;
	for(int i=cur[x],y;~i && flow<limit;i=Next[i]) {
		y=ver[cur[x]=i];
		if(edge[i] && dis[y]==dis[x]+w[i] && !vis[y]) {
			k=mcmf(y,min(edge[i],limit-flow));
			if(!k) dis[y]=-INF;
			edge[i]-=k; edge[i^1]+=k;
			flow+=k; ans+=k*w[i];
		}
	}
	vis[x]=false;
	return flow;
}

LL ww[N],v[N],siz[N];

void build(int l,int r)
{
	memset(one,-1,sizeof one); idx=0;
	S=n+m+1,T=n+m+2;
	
	for(int i=1;i<=n;i++) AddEdge(S,i,1,v[i]);
	for(int i=1;i<=m;i++) 
		if(i<l || i>r) AddEdge(i+n,T,1,0);
		
	for(int i=1;i<=n;i++) 
		for(int j=1;j<=m;j++) {
			if(l<=j && j<=r) continue;
			if(ww[i]<=siz[j]) AddEdge(i,j+n,1,0);
		}
}

int main()
{
//	freopen("1.in","r",stdin);
	int i;
	int x,y;
	
	scanf("%d%d%d",&n,&m,&Q);
	for(i=1;i<=n;i++) scanf("%lld%lld",&ww[i],&v[i]);
	for(i=1;i<=m;i++) scanf("%lld",&siz[i]);
	
	while(Q--) {
		scanf("%d%d",&x,&y);
		build(x,y);
		ans=0;
		while(spfa()) 
			while((x=mcmf(S,INF)));
	//			cerr<<x<<endl;
		printf("%lld\n",ans);
	}	
	return 0;
}

E Lucky 7 Battle

博弈论,DP。

关于一个“大”数是否是一个“小”数的倍数有个通用的状态设计,就是当前“大”数的前 \(i\)\(\bmod\) “小”数 的余数。

\(z=(10x+y) \bmod 7=((10x \bmod 7)+y) \bmod 7\)

逆推。

\(f[i][j]\) 表示操作到第 i 轮,目前 mod 7 = j , 能否一定 mod 7 余 0 .

若为 Takahashi , 则只要有一个成立即可。

若为 Aoki , 则要全部成立才成立。

Code:

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

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;

const int N=2e5+5;

int n;
char s[N],x[N];
int f[N][7]; 
// f[i][j] 表示操作到第 i 轮,目前 mod 7 = j , 能否一定 mod 7 余 0 .
// 若为 Takahashi , 则只要有一个成立即可。
// 若为 Aoki , 则要全部成立才成立。 

int dp(int i,int j)
{
	if(i==n) return (j==0);
	if(~f[i][j]) return f[i][j];
	if(x[i]=='T') f[i][j]=(dp(i+1,j*10%7)|dp(i+1,(j*10+s[i]-'0')%7));
	else f[i][j]=(dp(i+1,j*10%7)&dp(i+1,(j*10+s[i]-'0')%7));
//	printf("f[%d][%d] = %d\n",i,j,f[i][j]);
	return f[i][j];
}

int main()
{
//	freopen("1.in","r",stdin);	
	memset(f,-1,sizeof f);
	scanf("%d",&n);
	scanf("%s",s); scanf("%s",x);
	if(dp(0,0)) puts("Takahashi");
	else puts("Aoki");
	return 0;
}

F Coprime Present

还不会。。。

posted @ 2021-03-13 23:00  cjlworld  阅读(281)  评论(0编辑  收藏  举报