AtCoder Beginner Contest 374

ABC374 A - Takahashi san 2

题目传送门


代码(签到题)

#include <cstdio>
#include <cctype>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
int iut(){
	int ans=0,f=1; char c=getchar();
	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
	return ans*f;
}
void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
int main(){
	char s[111]; int len;
	scanf("%s",s+1),len=strlen(s+1);
	if (s[len-2]=='s'&&s[len-1]=='a'&&s[len]=='n'){
		printf("Yes");
	}else printf("No");
	return 0;
}

ABC374 B - Unvarnished Report

题目传送门


代码(签到题)

#include <cstdio>
#include <cctype>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
char s[111],t[111]; int n,m;
int iut(){
	int ans=0,f=1; char c=getchar();
	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
	return ans*f;
}
void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
int main(){
	scanf("%s",s+1),n=strlen(s+1);
	scanf("%s",t+1),m=strlen(t+1);
	for (int i=1;i<=n||i<=m;++i)
	if (s[i]!=t[i]){
		return !printf("%d",i);
	} 
	return !printf("0");
}

ABC374 C - Separated Lunch

题目传送门


代码(签到题)

#include <cstdio>
#include <cctype>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
int n,a[111],ans,sum;
int iut(){
	int ans=0,f=1; char c=getchar();
	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
	return ans*f;
}
void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
int main(){
	n=iut();
	for (int i=0;i<n;++i) a[i]=iut(),sum+=a[i];
	ans=sum;
	for (int i=2;i<(1<<n);i+=2){
		int now=0;
		for (int j=0;j<n;++j)
		    if ((i>>j)&1) now+=a[j];
		ans=min(ans,max(now,sum-now));
	}
	return !printf("%d",ans);
}

ABC374 D - Laser Marking

题目传送门


代码(签到题)

#include <cstdio>
#include <cctype>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
const int N=111; double ans=1e18;
int n,v1,v2,x[N][2],y[N][2],rk[N];
int iut(){
	int ans=0,f=1; char c=getchar();
	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
	return ans*f;
}
void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
double o(int lx,int ly,int rx,int ry){return sqrt((rx-lx)*(rx-lx)+(ry-ly)*(ry-ly));}
int main(){
	n=iut(),v1=iut(),v2=iut();
	for (int i=1;i<=n;++i){
		x[i][0]=iut(),y[i][0]=iut();
		x[i][1]=iut(),y[i][1]=iut();
		rk[i]=i;
	}
	do{
		for (int i=0;i<(1<<n);++i){
			int lstx=0,lsty=0; double now=0;
			for (int j=1;j<=n;++j){
				int z=(i>>(j-1))&1;
				now+=o(lstx,lsty,x[rk[j]][z],y[rk[j]][z])/v1;
				lstx=x[rk[j]][z^1],lsty=y[rk[j]][z^1];
				now+=o(lstx,lsty,x[rk[j]][z],y[rk[j]][z])/v2;
			}
			ans=min(ans,now);
		}
	}while (next_permutation(rk+1,rk+1+n));
    printf("%.12lf",ans);
}

ABC374 E - Sensor Optimization Dilemma 2

题目传送门


分析

二分答案,这样就变成每种机器有最低产量限制,且让总费用最小,而单个最小值的枚举机器个数是在 \(\max\{a_i,b_i\}\) 范围内的,考场写了假的三分故意扩大 eps 然后过了


代码

#include <cstdio>
#include <cctype>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
const int N=111;
typedef long long lll;
int w[N][2],c[N][2],n,X;
int iut(){
	int ans=0,f=1; char c=getchar();
	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
	return ans*f;
}
void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
lll calc(lll j,int i,int mid){
	if (mid>j*c[i][0]) return j*w[i][0]+(mid-j*c[i][0]+c[i][1]-1)/c[i][1]*w[i][1];
	    else return j*w[i][0];
}
bool check(int mid){
	lll sum=0;
	for (int i=1;i<=n;++i){
		lll now=1e18,lim=(mid+c[i][0]-1)/c[i][0];
		for (int j=0;j<=c[i][1];++j) now=min(now,calc(j,i,mid));
		for (int j=lim;j>=lim-c[i][0]&&j>=0;--j) now=min(now,calc(j,i,mid));
		sum+=now;
		if (sum>X) return 0;
	}
	return 1;
}
int main(){
	n=iut(),X=iut();
	for (int i=1;i<=n;++i){
		c[i][0]=iut(),w[i][0]=iut();
		c[i][1]=iut(),w[i][1]=iut();
		if (c[i][0]<c[i][1]) swap(c[i][0],c[i][1]),swap(w[i][0],w[i][1]);
	}
	int l=0,r=0x3f3f3f3f;
	while (l<r){
		int mid=(l+r+1)>>1;
		if (check(mid)) l=mid;
		    else r=mid-1;
	}
	return !printf("%d",l);
}

ABC374 F - Shipping

题目传送门


分析

本题动态规划一定要利用时刻,而有效的时刻就是 \(T_i+kX\)\(O(n^2)\) 个。

\(dp[i][j]\) 表示时刻 \(i\) 或以前已经让前 \(j\) 艘船通过的最小值,直接 \(O(n^3k)\) 即可


代码

#include <cstdio>
#include <cctype>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
const int N=111;
typedef long long lll;
lll n,m,k,X,a[N],dp[N*N][N],b[N*N];
lll iut(){
	lll ans=0,f=1; char c=getchar();
	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
	return ans*f;
}
int main(){
	n=iut(),k=iut(),X=iut();
	for (int i=1;i<=n;++i){
		a[i]=iut();
		for (int j=0;j<n;++j) b[++m]=a[i]+j*X;
	}
	sort(b+1,b+1+m),m=unique(b+1,b+1+m)-b-1;
	for (int i=0;i<=m;++i)
	for (int j=0;j<=n;++j) dp[i][j]=1e18;
	dp[0][0]=0,b[0]=-X;
	for (int i=1,I=0;i<=m;++i){
		while (I<=m&&b[I]+X<=b[i]) ++I; --I;
		for (int j=0;j<=n;++j){
			if (b[i]<a[j]) break;
			dp[i][j]=dp[i-1][j];
			lll sum=0;
			for (int o=0;o<=k&&o<=j;++o)
			    dp[i][j]=min(dp[i][j],dp[I][j-o]+sum),sum+=b[i]-a[j-o];
		}
	}
	return !printf("%lld",dp[m][n]);
}

ABC374 G - Only One Product Name

题目传送门


分析

最多有 \(26^2\) 个点的有向图,求最小可相交路径覆盖,由于可相交,不妨先将该有向图缩点成 DAG,

在新图传递闭包,答案为新图点数减去最大匹配数


代码

#include <iostream>
#include <string>
#include <stack>
#include <bitset>
using namespace std;
const int N=911; bitset<N>a[N]; string str[N];
struct node{int y,next;}e[N*N]; stack<int>st;
int dfn[N],low[N],v[N],col[N],tot,cnt,n,upd,link[N],et=1,ans,as[N];
void tarjan(int x){
	dfn[x]=low[x]=++tot,v[x]=1,st.push(x);
	for (int i=as[x];i;i=e[i].next)
	if (!dfn[e[i].y]){
		tarjan(e[i].y);
		low[x]=min(low[x],low[e[i].y]);
	}else if (v[e[i].y]) low[x]=min(low[x],dfn[e[i].y]);
	if (dfn[x]==low[x]){
		int y; ++cnt;
		do{
			y=st.top(); st.pop();
			col[y]=cnt,v[y]=0;
		}while (y!=x);
	}
}
bool match(int x){
	for (int y=1;y<=cnt;++y)
	if (a[x][y]&&v[y]!=upd){
		v[y]=upd;
		int q=link[y];
		link[y]=x;
		if (!q||match(q)) return 1;
		link[y]=q;
	}
	return 0;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n;
	for (int i=1;i<=n;++i) cin>>str[i];
	for (int i=1;i<=n;++i)
	for (int j=1;j<=n;++j)
	if (str[j][0]==str[i][1]){
		e[++et]=(node){j,as[i]},as[i]=et;
	}
	for (int i=1;i<=n;++i) if (!dfn[i]) tarjan(i);
	for (int i=1;i<=n;++i)
	for (int j=as[i];j;j=e[j].next)
	    if (col[i]!=col[e[j].y]) a[col[i]][col[e[j].y]]=1;
	for (int k=1;k<=cnt;++k)
	for (int i=1;i<=cnt;++i)
	    if (a[i][k]) a[i]|=a[k];
	for (int i=1;i<=cnt;++i){
		++upd;
		if (match(i)) ++ans;
	}
	cout<<cnt-ans;
	return 0;
}

posted @ 2024-10-07 15:32  lemondinosaur  阅读(20)  评论(0编辑  收藏  举报