• 欢迎光临~

“统信杯” 第十七届黑龙江省大学生程序设计竞赛

开发技术 开发技术 2022-05-30 次浏览

A:Bookshelf Filling

分析:只能横着放 并且右边b至少还剩下一个 最小化宽度

可以先把横着能放的都先放过去 剩下的就是空格 最后二分一下就好

细节挺多的

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int T;
ll L,R,res,mid,a,b,n,m,h,RR;
void solve();
bool ck(ll);
int main(){
    cin>>T;
    while(T--)solve();
    return 0;
}
bool ck(ll x){
    ll now=res+x;
    ll sum=now/b*(h-b);
    if(sum>=RR-x)return true;
    return false;
}
void solve(){
    scanf("%lld%lld%lld%lld%lld",&a,&b,&n,&m,&h);
    R=m-((n/b)*(h-a));
    RR=R;
    res=n-(n/b)*b;
    L=1;
    ll G=1;
    while(L<=R){
         mid=L+R>>1;
        if(ck(mid))R=mid-1,G=mid;
        else L=mid+1;
    }
    cout<<n+G<<endl;
}
/*
1
1 5 5 1 5
*/

C:
Tree Division

分析: 一个点只有分为A或者B 只要遍历一下树 同时记录一下A组的最大值 B组的最小值

只要A组的最大值满足 则路径上所有A组的点都满足 同理B组

遇到该点A B两组都可以选的情况下 分别进行dfs即可

#include<bits/stdc++.h>
using namespace std;
int n,ver[200010],hed[200010],nxt[200010],f[200010],tot=0;
void add(int x,int y){
	ver[++tot]=y,nxt[tot]=hed[x],hed[x]=tot;
}
bool dfs(int x,int minn,int maxx,int fa){
	int ans=1;
	for(int i=hed[x];i;i=nxt[i]){
		int y=ver[i];
		if(y==fa)
			continue;
		if((f[y]>maxx)&&(f[y]<minn))
			ans=ans&(dfs(y,minn,f[y],x)||dfs(y,f[y],maxx,x));
		else if(f[y]>maxx)
			ans=ans&dfs(y,minn,f[y],x);
		else if(f[y]<minn)
			ans=ans&dfs(y,f[y],maxx,x);
		else
			ans=0;
		if(ans==0)
			break;
	}
	return ans;
}
int main(){
	int anss;
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
		scanf("%d",&f[i]);
	for(int i=1;i<n;++i){
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v),add(v,u);
	}
	dfs(1,f[1],0,1)||dfs(1,10000000,f[1],1)?puts("YES"):puts("NO");
	return 0;
}

“统信杯” 第十七届黑龙江省大学生程序设计竞赛

发现两两点之间的最短路径是知道的

所以(a,b) 到 (c,d) 答案就是min(dis[a,c]+dis[b,d],dis[b,c]+dis[a,d])

这个时候会有疑问 会不会移动一个棋子会把另一个棋子的路挡住

肯定是不会的 因为挡住了可以先走另一个棋子 并且还有很多对棋子的最短路可能会有两条

 #include<bits/stdc++.h>
using namespace std;
int a[8][8];
int line[8];
int T;
void solve();
int main(){
    line[1]=1,line[2]=line[3]=2,line[4]=3,line[5]=line[6]=4,line[7]=5;
    for(int i=1;i<=7;i++){
        for(int j=i+1;j<=7;j++){
            if(line[i]==line[j])
            a[i][j]=a[j][i]=2;
            else a[i][j]=a[j][i]=(line[j]-line[i]);
        }
    }
    cin>>T;
    while(T--)solve();
    return 0;
} 
void solve(){
    int aa,bb,cc,dd;
    scanf("%d%d%d%d",&aa,&bb,&cc,&dd);
    printf("%dn",min(a[aa][cc]+a[bb][dd],a[aa][dd]+a[bb][cc]));
}

“统信杯” 第十七届黑龙江省大学生程序设计竞赛
这个题就是一道进栈退栈的模拟题

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+5;
int n,cnt;
string s;
stack<int>stk;
int ans[maxn];
int main(){
    cin>>n;
    cin>>s;
    for(int i=0;i<s.size();i++){
        if(s[i]=='-')
        ans[++cnt]=i;
        else if(s[i]=='(')
        stk.push(i);
        else if(s[i]==')'){
            ans[++cnt]=i;
            ans[++cnt]=stk.top();
            stk.pop();
        }
    }
    for(int i=1;i<=cnt;i++)cout<<ans[i]+1<<" ";
    return 0;
}

“统信杯” 第十七届黑龙江省大学生程序设计竞赛
开始以为爆搜会T 但是发现不会 而且跑得很快

又是一道签到题(不得不吐槽黑龙江省赛签到题有点多啊)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll ans,n;
void dfs(ll);
int main(){
    cin>>n;
    dfs(0);
    cout<<ans<<endl;
    return 0;
}
void dfs(ll now){
    if(now>n)return;
    if(now==n){
        ans++;
        return;
    }
    for(ll i=1;i<=n;i++)
    dfs(now+i);
}

D题(计算几何)

待补

E题

待补

L题

待补

G题

待补

程序员灯塔
转载请注明原文链接:“统信杯” 第十七届黑龙江省大学生程序设计竞赛
喜欢 (0)