赛后练习,慢慢找感觉
A要考虑很多种情况,特别是坐m站路车的距离大于n但是更便宜的情况
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m,a,b;
int main(){
while(cin>>n>>m>>a>>b){
int x=a*m;
if(x<b){
cout<<a*n<<endl;
}else{
int res=0;
if(m>n){
if(b>n*a){
res=n*a;
}else{
res=b;
}
}else{
res+=(n/m*b);
res+=n%m*a;
res=min(res,n/m*b+b);
}
cout<<res<<endl;
}
}
return 0;
}
B,贪心思路,从6*n开始向上枚举房间的面积,存在符合的则输出,注意要用int64
#include<iostream>#include<cstring>#include<cstdio>#include<cmath>usingnamespace std;longlong n,a,b;int inprim(longlong aaa,longlong&beg,longlong&edd){longlong i;longlong k=sqrt(aaa);for(i=beg;i<=k;i++){if(aaa%i==0&&aaa/i>=edd){ beg=i; edd=aaa/i;return i;}}return-1;}int main(){while(scanf("%I64d",&n)!=EOF){ scanf("%I64d%I64d",&a,&b);if(n*6<=a*b){ printf("%I64d\n",a*b); printf("%I64d %I64d\n",a,b);continue;} n*=6;longlong res;while(1){longlong edd=max(a,b);longlong beg=min(a,b);longlong flag=inprim(n,beg,edd);if(flag!=-1){ res=beg*edd;if(a<=beg){ a=beg,b=edd;}else{ b=beg,a=edd;}break;} n++;} printf("%I64d\n",res); printf("%I64d %I64d\n",a,b);}return0;}
C,比B要水,遍历两遍即可
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int num[600000],n,dp[600000];
int main(){
int i;
long long sum,res;
while(scanf("%d",&n)!=EOF){
res=sum=0;
for(i=1;i<=n;i++){
scanf("%d",&num[i]);
sum+=num[i];
}
if(sum%3!=0){
printf("0\n");
continue;
}
sum/=3;
memset(dp,0,sizeof(dp));
long long suml=0,sumr=0;
for(i=n;i>0;i--){
sumr+=num[i];
dp[i]=dp[i+1];
if(sumr==sum){
dp[i]++;
}
}
for(i=1;i<n;i++){
suml+=num[i];
if(suml==sum){
res+=dp[i+2];
}
}
// for(i=1;i<=n;i++)cout<<dp[i]<<" ";
// cout<<endl;
printf("%I64d\n",res);
}
return 0;
}
D 没看懂样例,留着坑回来填
E 并查集的好题,题意是给出一些人和他上司的关系图,第a个人知道第i条消息后,这个人的上司以及上司的上司都会知道这个消息。在线的询问,第x人知不知道第k条消息
这题技巧在于,每次都记录知道第i条消息人关系链的头和尾,输入第x个人和第i条消息后,看他是不是在第i条消息关系链的头和尾上即可。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int nMax=100005;
int father[nMax],boss[nMax];
int find(int x){ // 寻找父节点
if(x!=father[x])
return father[x]=find(father[x]);
return x;
}
void init(){ // 初始化
int i;
for(i=0; i<nMax-1; i++){
boss[i]=father[i]=i;
}
}
int vv1[nMax],vv2[nMax];
int main(){
int n,m,a,b,c,nk;
while(scanf("%d%d",&n,&m)!=EOF){
init();
nk=1;
while(m--){
scanf("%d",&a);
if(a==1){
scanf("%d%d",&b,&c);
boss[b]=c;
father[b]=c;
}else if(a==2){
scanf("%d",&b);
vv1[nk]=b;
vv2[nk++]=find(b); //第nk条信息由第b人穿到第findb人
}else if(a==3){
scanf("%d%d",&b,&c); //第b个人,第c条信息
bool flag=0;
int beg=vv1[c];
int edd=vv2[c]; //第c条消息的开始和结束
while(true){
if(beg==b){
flag=1;
break;
}if(beg==edd){
break;
}
beg=boss[beg];
}
if(flag){printf("YES\n");}
else printf("NO\n");
}
}
}
return 0;
}