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题
待补