2021-10-05模拟赛总结

Posted scj2021

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021-10-05模拟赛总结相关的知识,希望对你有一定的参考价值。


总括

题数:4
时间:4h
得分:290


一、寻找道路

P2296 寻找道路
来源:洛谷(NOIP2014 提高组)
算法:图论,搜索,模拟水题
得分:100
代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,ss,ee;
bool p1[10005],p2[10005];
int head1[200005],nxt1[200005],ver1[200005],tot1=0;
int head2[200005],nxt2[200005],ver2[200005],tot2=0;
queue<int> w;
int dis[10005];
void add1(int x,int y){
	ver1[++tot1]=y,nxt1[tot1]=head1[x],head1[x]=tot1;
}
void add2(int x,int y){
	ver2[++tot2]=y,nxt2[tot2]=head2[x],head2[x]=tot2;
}

int main(){
	scanf("%d%d",&n,&m);
	memset(p1,0,sizeof(p1));
	memset(p2,0,sizeof(p2));
	memset(dis,0,sizeof(dis));
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		add1(x,y);
		add2(y,x);
	}
	scanf("%d%d",&ss,&ee);
	w.push(ee);
	p2[ee]=1;
	while(!w.empty()){
		int temp=w.front();
		w.pop();
		for(int i=head2[temp];i;i=nxt2[i]){
			int y=ver2[i];
			if(!p2[y]){
				p2[y]=1;
				w.push(y);
			}
		}
	}
	if(p2[ss]==0){
		cout<<-1;
		return 0;
	}
	for(int i=1;i<=n;i++){
		if(p2[i]==1){
			p1[i]=1;
			for(int j=head1[i];j;j=nxt1[j]){
				int y=ver1[j];
				if(p2[y]==0){
					p1[i]=0;
					break;
				}
			}
		}
	}
	if(p1[ss]==0){
		cout<<-1;
		return 0;
	}
	dis[ss]=1,w.push(ss);
	while(!w.empty()){
		int temp=w.front();
		w.pop();
		if(temp==ee){
			cout<<dis[ee]-1;
			return 0;
		}
		for(int i=head1[temp];i;i=nxt1[i]){
			int y=ver1[i];
			if(p1[y]&&dis[y]==0){
				dis[y]=dis[temp]+1;
				w.push(y);
			}
		}
	}
	cout<<-1;
	return 0;
}

反思:水就是水!!!


二、国王游戏

P1080 国王游戏
来源:洛谷(NOIP2012 提高组)
算法:高精度,贪心,数学
得分:60
代码:

#include<bits/stdc++.h>
using namespace std;
int n;
struct node{
	int a;
	int b;
	int c;
	int d;
	int e;
}m[1010];
bool cmp(node x,node y){
	return x.c<y.c;
}
long long ans=-1;
int main(){
	scanf("%d",&n);
	for(int i=0;i<=n;i++){
		scanf("%d%d",&m[i].a,&m[i].b);
		m[i].c=m[i].a*m[i].b;
		m[i].d=0;
		m[i].e=1;
	}
	sort(m+1,m+1+n,cmp);
	for(int i=1;i<=n;i++){
		for(int j=0;j<i;j++){
			int t1=m[j].a/m[i].b,t2=m[j].a%m[i].b;
			m[i].d=m[i].d*t1*m[i].b+m[i].d*t2+m[i].e*t1;
			m[i].e=m[i].e*t2;
			m[i].d+=m[i].e/m[i].b;
			m[i].e%=m[i].b;
		}
		if(ans==-1||ans<m[i].d) ans=m[i].d;
	}
	cout<<ans;
	return 0;
}

正解:

#include <bits/stdc++.h>
using namespace std;
int now[20010],sum[20010],ans[20010],add[20010];
struct Node {
    int a;
    int b;
    long long a_b;
}node[1010];
int read() {
    int ans=0,flag=1;
    char ch=getchar();
    while( (ch>'9' || ch<'0') && ch!='-' ) ch=getchar();
    if(ch=='-') flag=-1,ch=getchar();
    while(ch>='0' && ch<='9') ans=ans*10+ch-'0',ch=getchar();
    return ans*flag;
}
void times(int x) {
    memset(add,0,sizeof(add));
    for(int i=1;i<=ans[0];i++) {
        ans[i]=ans[i]*x;
        add[i+1]+=ans[i]/10;
        ans[i]%=10;
    }
    for(int i=1;i<=ans[0]+4;i++) {
        ans[i]+=add[i];
        if(ans[i]>=10) {
            ans[i+1]+=ans[i]/10;
            ans[i]%=10;
        }
        if(ans[i]!=0) {
            ans[0]=max(ans[0],i);
        } 
    }
    return ;
}
int divition(int x) {
    memset(add,0,sizeof(add));
    int q=0;
    for(int i=ans[0];i>=1;i--) {
        q*=10;
        q+=ans[i];
        add[i]=q/x;
        if(add[0]==0 && add[i]!=0) {
            add[0]=i;
        }
        q%=x; 
    }
    return 0;
}
bool compare() {
    if(sum[0]==add[0]) {
        for(int i=add[0];i>=1;i--) {
            if(add[i]>sum[i]) return 1;
            if(add[i]<sum[i]) return 0;
        }
    }
    if(add[0]>sum[0]) return 1;
    if(add[0]<sum[0]) return 0;
}
void cp () {
    memset(sum,0,sizeof(sum));
    for(int i=add[0];i>=0;i--) {
        sum[i]=add[i];
    }
    return ;
}
bool cmp(Node a,Node b) {
    return a.a_b<b.a_b;
}
int main() {
    int n=read();
    for(int i=0;i<=n;i++) {
        node[i].a=read(),node[i].b=read();
        node[i].a_b=node[i].a*node[i].b;
    }
    sort(node+1,node+n+1,cmp);
    ans[0]=1,ans[1]=1;
    for(int i=1;i<=n;i++) {
        times(node[i-1].a);
        divition(node[i].b);
        if(compare()) {
            cp();
        }
    }
    for(int i=sum[0];i>=1;i--)
        printf("%d",sum[i]);
    return 0;
} 

反思:正常算法白嫖60分不成问题,满分需要高精度,有时间再写!!!


三、书柜的尺寸

P2160 书柜的尺寸
来源:洛谷(SHOI2007 省选)
算法:动态规划,排序,滚动数组
得分:100
代码:

#include<bits/stdc++.h>
using namespace std;
struct node{
	int h;
	int t;
}a[80];
int n,sum[80],f[2][2105][2105];
bool cmp(node x,node y){
	return x.h>y.h;
}
int main(){    
	long long ans=1<<30;
	scanf("%d",&n);
	sum[0]=0;
	for(int i=1;i<=n;i++) scanf("%d%d",&a[i].h,&a[i].t);
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i].t;
	memset(f,0x3f,sizeof(f));
	f[0][0][0]=0;
    int now,pre;
    for (int i=1;i<=n;i++){
        now=i&1;pre=now^1;
        memset(f[now],0x3f,sizeof(f[now]));
        for (int j=0;j<=sum[i];j++){
            for (int k=0;k<=sum[i];k++){
            	if (f[pre][j][k]!=0x3f){
                	if(j==0)
						f[now][j+a[i].t][k]=min(f[now][j+a[i].t][k],f[pre][j][k]+a[i].h);
					else
						f[now][j+a[i].t][k]=min(f[now][j+a[i].t][k],f[pre][j][k]);
						
					if(k==0)
						f[now][j][k+a[i].t]=min(f[now][j][k+a[i].t],f[pre][j][k]+a[i].h);
					else
						f[now][j][k+a[i].t]=min(f[now][j][k+a[i].t],f[pre][j][k]);
						
					if(sum[i-1]-j-k==0)
						f[now][j][k]=min(f[now][j][k],f[pre][j][k]+a[i].h);
					else
						f[now][j][k]=min(f[now][j][k],f[pre][j][k]);
				}
			}
        }
    }
    for(int i=1;i<=sum[n];i++)
        for(int j=1;j<=sum[n];j++)
        if(sum[n]-i-j)
			ans=min(ans,(long long)max(max(i,j),sum[n]-i-j)*(long long)f[now][i][j]);    
    cout<<ans;
	return 0;
}

反思:没什么


四、海底珍珠串



来源:大师兄原创题
算法:模拟,贪心
得分:
代码:

#include<bits/stdc++.h>
using namespace std;
int n,a[200005],ans=0;
int b[30],ous,even,f,e;
char s;
void repe(int fir){
	memset(b,0,sizeof(b));
	even=0,ous=n-fir+1;
	for(int i=fir;i<=n;i++){
		b[a[i]]++;
		if(b[a[i]]%2==0) even--,ous++;
		else even++,ous--;
	}
}
int main(){
	scanf("%d",&n);
	ous=n;
	s=getchar();
	for(int i=1;i<=n;i++){
		s=getchar();
		a[i]=s-'a'+1;
		b[a[i]]++;
		if(b[a[i]]%2==0) even--,ous++;
		else even++,ous--;
	}
	s=getchar();
	f=1,e=n;
	while(f<=n){
		if(f>e){
			f++;
			e=n;
			ans++;
			repe(f);
			continue;
		}
		if(even==1||even==0){
			f=e+1;
			e=n;
			repe(f);
			ans++;
		}
		else{
			if(b[a[e]]%2==0) ous--,even++;
			else ous++,even--;
			b[a[e]]--;
			e--;
		}
	}
	cout<<ans;
	return 0;
}

反思:

以上是关于2021-10-05模拟赛总结的主要内容,如果未能解决你的问题,请参考以下文章

2021-10-05模拟赛

python常用代码片段总结

BootStrap有用代码片段(持续总结)

BootStrap实用代码片段(持续总结)

回归 | js实用代码片段的封装与总结(持续更新中...)

查看发票组代码后的总结和有感