“統信杯” 第十七屆黑龍江省大學生程式設計競賽
阿新 • • 發佈: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("%d\n",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題
待補