codeforces #270 ABCD

时间:2023-03-09 01:34:52
codeforces #270 ABCD

Codeforces Round #270

A - Design Tutorial: Learn from Math

题意:给出n,求出两个合数x和y使x+y=n。

题解:暴力筛合数,然后暴力找

 //#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#include<queue>
using namespace std;
#define ll __int64
#define usint unsigned int
#define mz(array) memset(array, 0, sizeof(array))
#define minf(array) memset(array, 0x3f, sizeof(array))
#define REP(i,n) for(int i=0;i<(n);i++)
#define FOR(i,x,n) for(int i=(x);i<=(n);i++)
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define WN(x) printf("%d\n",x);
#define RE freopen("D.in","r",stdin)
#define WE freopen("1.out","w",stdout) bool a[]; int main() {
int x,i,n,j;
RD(n);
int n2=n/;
for(x=; x<=n2; x++) {
if(a[x]==) {
for(i=x+x; i<=n; i+=x) {
a[i]=;
}
}
}
for(x=;x<=n2;x++){
if(a[x]== && a[n-x]==)break;
}
printf("%d %d\n",x,n-x);
return ;
}

B - Design Tutorial: Learn from Life

题意:一堆人从1楼坐电梯,电梯一次最多装K人,给出各个人要去的各个楼层,上下电梯时间忽略不计,电梯移动一层需要1秒,求最少需要多少时间才能送完所有人并且电梯回到1楼。

题解:贪心,优先送最高的,空位顺便送低的。

 //#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#include<queue>
using namespace std;
#define ll __int64
#define usint unsigned int
#define mz(array) memset(array, 0, sizeof(array))
#define minf(array) memset(array, 0x3f, sizeof(array))
#define REP(i,n) for(int i=0;i<(n);i++)
#define FOR(i,x,n) for(int i=(x);i<=(n);i++)
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define WN(x) printf("%d\n",x);
#define RE freopen("D.in","r",stdin)
#define WE freopen("1.out","w",stdout) int a[]; int main() {
int n,k,i,j,x,ans;
RD2(n,k);
REP(i,n) {
RD(x);
a[x]++;
}
x=;
ans=;
for(i=;i>=;i--) {
if(a[i]>) {
a[i]-=x;
int t=a[i]/k;
int tt=t*k;
int ttt=tt>=a[i]?t:t+;
ans+=ttt*(i-)*;
x=ttt*k-a[i];
//printf("%d %d %d\n",i,ttt,ans);
}
}
WN(ans);
return ;
}

C - Design Tutorial: Make It Nondeterministic

题意:每个人可以用自己的姓或者名字作为ID,给出各个人的名字,给出一个排名序列,若有一种选择ID的方法可以使排名正确,则输出YES,否则输出NO。

题解:贪心,排名1的人选字典序少的那个,然后都优先选字典序小的,不行了就选大的,再不行就NO。

 //#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#include<queue>
using namespace std;
#define ll __int64
#define usint unsigned int
#define mz(array) memset(array, 0, sizeof(array))
#define minf(array) memset(array, 0x3f, sizeof(array))
#define REP(i,n) for(int i=0;i<(n);i++)
#define FOR(i,x,n) for(int i=(x);i<=(n);i++)
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define WN(x) printf("%d\n",x);
#define RE freopen("D.in","r",stdin)
#define WE freopen("1.out","w",stdout) char s[][][]; int cmp(char a[],char b[]) {
int la=strlen(a),lb=strlen(b);
int l=min(la,lb);
int i;
for(i=; i<l; i++) {
if(a[i]>b[i])return ;
if(b[i]>a[i])return -;
}
if(la>lb)return ;
if(lb>la)return -;
return ;
} int main() {
int n;
RD(n);
REP(i,n) {
scanf(" %s%s",s[i][],s[i][]);
//printf("%d %s!%s!\n",i,s[i][0],s[i][1]);
}
char q[];
int x,y=,z,j;
RD(x);
y=x-;
if(cmp(s[y][],s[y][])==-) z=;
else z=;
bool flag=;
REP(i,n-) {
RD(x);
x--;
if(cmp(s[x][],s[x][])==-) j=;
else j=;
if(cmp(s[x][j] , s[y][z])==-){
if(cmp(s[x][j^], s[y][z])==-){
flag=;
break;
}else{
y=x;
z=j^;
}
}else{
y=x;
z=j;
}
}
if(flag)puts("YES");
else puts("NO");
return ;
}

D - Design Tutorial: Inverse the Problem

题意:给出各个点距离的邻接矩阵,判断这是不是一棵树。

题解:先根据样例特判一些情况,然后最小生成树,我是用可撸斯卡尔,当要加入的边的两个点x和y已经在同一集合,则判它们的距离是否正确。我的方法是找到一个中间点v,使x-v和v-y有路,找到(xv距离) + (vy距离)最小的那个值,当作x到y的距离。这是因为可撸斯卡尔是从小往大加边,肯定有至少一个中间点能使得这个有路。复杂度O(n^3),略高,姿势不对就要TLE……更好的解法可以看这里:http://www.cnblogs.com/forgot93/p/4000850.html

 //#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#include<queue>
using namespace std;
#define ll __int64
#define usint unsigned int
#define mz(array) memset(array, 0, sizeof(array))
#define mf1(array) memset(array, -1, sizeof(array))
#define minf(array) memset(array, 0x3f, sizeof(array))
#define REP(i,n) for(int i=0;i<(n);i++)
#define FOR(i,x,n) for(int i=(x);i<=(n);i++)
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define WN(x) printf("%d\n",x);
#define RE freopen("D.in","r",stdin)
#define WE freopen("1.out","w",stdout)
const int inf=*1e9+;
const int maxn=;
const int maxm=maxn*maxn; int a[][];
int n; int bx[maxm],by[maxm],bz[maxm];
int bn;
inline void add(const int &x,const int &y,const int &z){
bx[bn]=x;
by[bn]=y;
bz[bn]=z;
bn++;
} int d[maxm];
bool cmp(const int &x,const int &y){
return bz[x]<bz[y];
} int f[maxm];
int gf(const int &x){
if(f[x]==-)return x;
f[x]=gf(f[x]);
return f[x];
} struct Edge{
int next,v,l;
}e[maxm];
int head[maxn],en; inline void addedge(const int &x,const int &y,const int &z){
e[en].v=y;
e[en].l=z;
e[en].next=head[x];
head[x]=en;
en++;
} int dis[maxn][maxn]; inline void gank(const int &x,const int &y){
int mi=inf;
for(int i=head[x];i!=-;i=e[i].next){
if(dis[y][e[i].v]!=-){
//printf("(%d) %d + %d = %d\n",e[i].v,e[i].l,dis[y][e[i].v],e[i].l + dis[y][e[i].v]);
mi=min(mi , e[i].l + dis[y][e[i].v]);
}
}
dis[y][x]=dis[x][y]=mi;
} bool farm(){
int i,j,k,x,y,z;
bn=;
REP(i,n){
REP(j,n){
if(i!=j){
if(a[i][j]==)return ;
}else{
if(a[i][j]!=)return ;
}
}
}
REP(i,n){
REP(j,i){
if(a[i][j]!=a[j][i])return ;
add(i,j,a[i][j]);
}
}
REP(i,bn){
d[i]=i;
}
sort(d,d+bn,cmp);
mf1(f);
//mf1(head);
REP(i,n)REP(j,n)dis[i][j]=-;
en=;
mf1(head);
REP(i,n)dis[i][i]=;
//en=0;
REP(i,bn){
int q=d[i];
int &x=bx[q],&y=by[q],&z=bz[q];
int fx=gf(x),fy=gf(y);
if(fx!=fy){
addedge(x,y,z);
addedge(y,x,z);
dis[x][y]=z;
dis[y][x]=z;
f[fx]=fy;
}else{
if(dis[x][y]==-) gank(x,y);
//printf("dis[%d][%d]=%d , z=%d\n",x,y,dis[x][y],z);
if(dis[x][y]!=z)return ;
}
}
return ;
} int main() {
int i;
RD(n);
REP(i,n)REP(j,n) RD(a[i][j]);
if(farm())puts("YES");
else puts("NO");
return ;
}