“统信杯” 第十七届黑龙江省大学生程序设计竞赛(正式赛)IHFA(二分)
https://ac.nowcoder.com/acm/contest/34332#question
I-Equal Sum Arrays
题目大意:
f[n]表示可以凑出总和为n的集合数量;
给定n,求出f[n]。
- f[1]=1; f[2]=2; f[3]=4; f[4]= 8; ......
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL N=500200,M=2002;
int main()
{
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
LL T=1;
//cin>>T;
while(T--)
{
LL n;
cin>>n;
cout<<pow(2,n-1)<<endl;
}
return 0;
}
H-Kanbun
题目大意:
给定一个字符串s,问我们输出顺序是怎么样的?(从左到右)
要求:如果当前是“ - ” 或者 “ )”,直接输出,否则当前是“( ”的时候就必须要等到和它匹配的右括号一起输出。
输入
14
((-)-()--)(-)-
输出
3 4 2 5 7 6 8 9 10 1 12 13 11 14
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL N=500200,M=2002;
int main()
{
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
LL T=1;
//cin>>T;
while(T--)
{
LL n;
cin>>n;
string s;
cin>>s;
stack<int> st;
for(int i=0;i<s.size();i++)
{
if(s[i]=='-') cout<<i+1<<" ";
else if(s[i]=='(') st.push(i+1);
else if(s[i]==')')
{
cout<<i+1<<" ";
cout<<st.top()<<" ";
st.pop();
}
}
}
return 0;
}
F-342 and Xiangqi
题目大意:
就是求这七个点中的两个到另外两个点的最短距离是多少?
输入
3
1 5 1 7
2 7 4 6
2 3 3 2
输出
1
2
0
如果是我,我可能会打好长时间的表哈哈,队友直接弗洛伊德。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL N=500200,M=2002;
LL dist[M][M];
void init()
{
for(int i=1;i<=7;i++)
{
for(int j=1;j<=7;j++)
{
if(i==j) dist[i][j]=0;
else dist[i][j]=100;
}
}
dist[1][2]=dist[2][1]=1;
dist[1][3]=dist[3][1]=1;
dist[4][2]=dist[2][4]=1;
dist[3][4]=dist[4][3]=1;
dist[4][5]=dist[5][4]=1;
dist[4][6]=dist[6][4]=1;
dist[5][7]=dist[7][5]=1;
dist[6][7]=dist[7][6]=1;
for(int k=1;k<=7;k++)
{
for(int i=1;i<=7;i++)
{
for(int j=1;j<=7;j++)
{
dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
}
}
}
}
int main()
{
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
init();
LL T=1;
cin>>T;
while(T--)
{
LL x,y,a,b;
cin>>x>>y>>a>>b;
cout<<min(dist[x][a]+dist[y][b],dist[x][b]+dist[y][a])<<endl;
}
return 0;
}
A-Bookshelf Filling
题目大意:
给定两种书籍:A书籍高为a,宽为1,B书籍高为b,宽为1;A书籍有n本,B书籍有m本,一开始全部的书籍A都放在左边,然后B书籍都放在A的右边。
有一个柜子高为h,我们在放完了全部书籍之后可以发现,A书籍的上面还有一些空位,所以我们可以把B平躺着放上去,问我们最短的底边长是多少?
输入
4
2 5 5 8 5
2 4 5 7 5
2 6 5 2 6
3 4 3 2 5
输出
10
8
7
4
【注意】B书籍必须要留一本在A全部书籍的右边。也就是说地面边长最短都必须是(n+1)。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL N=500200,M=2002;
LL a,b,n,m,h;
int main()
{
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
LL T=1;
cin>>T;
while(T--)
{
cin>>a>>b>>n>>m>>h;
LL flag=(n/b)*(b-a);//在B和A之间的高度上我们可以塞多少本B?
//cout<<"flag "<<flag<<endl;
LL l=0,r=m-1;//放到和B高度平齐的那条线上面上:最少0本,最多m-1本
while(l<=r)
{
LL mid=l+r>>1;
//假设放上了mid本,所以底部长度为n+m-mid
//那么底部可以平铺(n+m-mid)/b本b,带上高度就总共是(n+m-mid)/b*(h-b)本
LL maxn=(n+m-mid)/b*(h-b);
//cout<<mid<<" "<<maxn<<endl;
if(flag+maxn<mid) r=mid-1;//最大化数量还放不下
else l=mid+1;//放得下
}
cout<<n+m-r<<endl;
}
return 0;
}