CCPC2018 吉林站 补题 | 题解

咕咕咕 慢速补题中qwq

A-a fool

求这个东西:
∑ i = 1 n ⌊ n i ⌋ \sum_{i=1}^{n}\lfloor{\frac{n}{i}}\rfloor i=1nin
整除分块即可

#include<bits/stdc++.h>
using namespace std;
int T,n,cnt;
int main(){
	#ifndef ONLINE_JUDGE
	freopen("ce.in","r",stdin);
	#endif
	scanf("%d",&T);
	while(T--){
		cnt++;
		scanf("%d",&n);
		int l=1,r=1;
		long long ans=0;
		while(l<=n&&r<=n){
			r=min(n,n/(n/l));
			ans+=(r-l+1)*(n/l);
			l=r+1;
		}
		if(ans%2==0) printf("Case %d: even\n",cnt);
		else printf("Case %d: odd\n",cnt);
	}
	return 0;
}

B- The World

按照题意模拟即可。

little skill: printf("%mkd",n) 可以输出k位字符长度的数字,不足k位前面用数字m补齐。

#include<bits/stdc++.h>
using namespace std;
int T,cnt;
map<string,int>tim;
int main(){
	#ifndef ONLINE_JUDGE
	freopen("ce.in","r",stdin);
	#endif
	scanf("%d",&T);
	tim["Beijing"]=8,tim["Washington"]=-5,tim["London"]=0,tim["Moscow"]=3;
	while(T--){
		cnt++;
		int now_h,now_m;
		scanf("%2d:%2d",&now_h,&now_m);
		char ch[3];
		scanf("%s",ch);
		if(ch[0]=='A'&&now_h==12) now_h=0;
		else if(ch[0]=='P'&&now_h!=12) now_h+=12;
		string s1,s2;
		cin>>s1>>s2;
		now_h+=tim[s2]-tim[s1];
		printf("Case %d: ",cnt);
		if(now_h<0) printf("Yesterday "),now_h=24+now_h;
		else if(now_h>=0&&now_h<24) printf("Today ");
		else printf("Tomorrow "),now_h-=24;
		if(now_h==0) printf("12:%02d AM",now_m);
		else if(now_h>0&&now_h<12) printf("%d:%02d AM",now_h,now_m);
		else if(now_h==12) printf("%d:%02d PM",now_h,now_m);
		else printf("%d:%02d PM",now_h-12,now_m);
		puts("");
	}
	return 0;
}

C-Justice

我们可以从2的1次方做起。每次多一个次方,需要的数量就*2。

#include<bits/stdc++.h>
#define MAXN 100010
using namespace std;
int T,cnt,n;
struct Node{int val,id,done;}t[MAXN];
inline bool cmp1(struct Node x,struct Node y){return x.val<y.val;}
inline bool cmp2(struct Node x,struct Node y){return x.id<y.id;}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&T);
    while(T--){
        cnt++;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&t[i].val);
            t[i].id=i;
        }
        sort(&t[1],&t[n+1],cmp1);
        for(int i=1;i<=n;i++) t[i].done=0;

        int need=1,i=1;
        bool flag1=false,flag2=false;
        for(int j=1;j<=1000000000&&i<=n;j++){
            while(i<=n&&t[i].val==j){
                need--;
                t[i].done=1;
                i++;
                if(need==0) break;
            }
            if(need==0){
                flag1=true;
                break;
            }
            if(1ll*need*2>n-i+1) break;
            need*=2;
        }
        if(flag1==true){
            // printf("i=%d\n",i);
            need=1;
            for(int j=1;j<=1000000000&&i<=n;j++){
                while(i<=n&&t[i].val==j){
                    need--;
                    t[i].done=0;
                    i++;
                    if(need==0) break;
                }
                if(need==0){
                    flag2=true;
                    break;
                }
                if(1ll*need*2>n-i+1) break;
                need*=2;
                // printf("j=%d need=%d i=%d\n",j,need,i);
            }
            if(flag2==true){
                printf("Case %d: YES\n",cnt);
                sort(&t[1],&t[n+1],cmp2);
                for(int j=1;j<=n;j++) printf("%d",t[j].done); puts("");
            }
            else{
                printf("Case %d: NO\n",cnt);
            }
        }
        else{
            printf("Case %d: NO\n",cnt);
        }
    }
    return 0;
}

D-The Moon

#include<bits/stdc++.h>
#define MAXN 210
using namespace std;
int T,p,q,cnt;
int done[MAXN];
double dp[MAXN];
inline double solve(int x){
    // printf("x=%d\n",x);
    if(done[x]) return dp[x];
    double fp=p/100.0;
    double fq=x/200.0;
    dp[x]=fp*(1-fq)*solve(min(200,x+4))+(1-fp)*solve(min(200,x+3))+1.0;
    done[x]=1;
    return dp[x];
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&T);
    while(T--){
        cnt++;
        memset(done,0,sizeof(done));
        memset(dp,0,sizeof(dp));
        q=4;
        scanf("%d",&p);
        done[200]=1,dp[200]=1.0/(p/100.0);
        printf("Case %d: %.10lf\n",cnt,solve(q));
    }
    return 0;
}

E-The Tower

相似+解方程写法

#include<bits/stdc++.h>
#define eps 1e-10
using namespace std;
int T,cnt;
double x,y,z,v1,v2,v3;
double t,r,h;
int main(){
	#ifndef ONLINE_JUDGE
	freopen("ce.in","r",stdin);
	#endif
	scanf("%d",&T);
	while(T--){
		cnt++;
		scanf("%lf%lf",&r,&h);
		scanf("%lf%lf%lf",&x,&y,&z);
		scanf("%lf%lf%lf",&v1,&v2,&v3);
		double cur_a=((v1*v1+v2*v2)*h*h-r*r*v3*v3);
		double cur_b=(2*v1*x*h*h+2*v2*y*h*h-2*v3*z*r*r+2*h*v3*r*r);
		double cur_c=((x*x+y*y)*h*h-(h*h+z*z-2*h*z)*r*r);
		double delta=cur_b*cur_b-4*cur_a*cur_c;
		double ans1=(-cur_b+sqrt(delta))/(2*cur_a);
		double ans2=(-cur_b-sqrt(delta))/(2*cur_a);

        if(ans1>ans2) swap(ans1,ans2);
		double x1=x+ans1*v1,y1=y+ans1*v2,z1=z+ans1*v3;
        double x2=x+ans2*v1,y2=y+ans2*v2,z2=z+ans2*v3;
        bool flag1=true,flag2=true;
        if(z1<0||z1>h||x1*x1+y1*y1>r*r+eps) flag1=false;
        if(z2<0||z2>h||x2*x2+y2*y2>r*r+eps) flag2=false;
        if(ans1>eps&&flag1==true) printf("Case %d: %0.10lf\n",cnt,ans1);
        else printf("Case %d: %0.10lf\n",cnt,ans2);
	}
	return 0;
}

二分写法(来自队友zyf)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll INF=1e5+720;
const double eps=1e-6,eps_large=1e-6,eps_mini=1e-6;
int T;
double r0,h0,x0,y0,z0,vx,vy,vz;
bool in_tower(double x,double y,double z)
{
	if(z>h0||z<0) return 0;
	double r=r0*(h0-z)/h0;
	return x*x+y*y<r*r+eps_mini;
}
double dist(double x,double y,double z)
{
	if(z>h0) return 1.0*INF;
	double r=r0*(h0-z)/h0;
	return sqrt(x*x+y*y)-r;
}
int check(double t)
{
	double x=x0+t*vx,y=y0+t*vy,z=z0+t*vz;
	if(in_tower(x,y,z)) return 1;
	if(z<-eps_mini) return vz>0?0:2;
	if(z>h0+eps_mini) return vz>0?2:0;
	if(dist(x,y,z)<eps_mini+dist(x+eps_large*vx,y+eps_large*vy,z+eps_large*vz)) return 2;
	return 0;
}
int main()
{
	scanf("%d",&T);
	for(int tt=1;tt<=T;tt++)
	{
		scanf("%lf%lf",&r0,&h0);
		scanf("%lf%lf%lf%lf%lf%lf",&x0,&y0,&z0,&vx,&vy,&vz);
		double l=0,r=1.0*INF;
		while(r-l>eps)
		{
			double mid=(l+r)/2;
			//printf("l=%.8lf,r=%.8lf\n",l,r);
			int ck=check(mid);
			if(ck==0) l=mid;
			else r=mid;
		}
		printf("Case %d: %.10lf\n",tt,l);
	}
	return 0;
}

F-The Hermit

G-High Priestess

H-Lovers

I-Strength

#include<bits/stdc++.h>
#define MAXN 100010
using namespace std;
int T,cnt,n,m;
int a[MAXN],cur[MAXN];
struct Node{int id,val;}b[MAXN];
inline bool cmp1(int x,int y){return x<y;}
inline bool cmp2(int x,int y){return x>y;}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&T);
    while(T--){
        long long ans=0;
        cnt++;
        bool flag=true;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=m;i++) scanf("%d",&b[i].val);
        for(int i=1;i<=m;i++) scanf("%d",&b[i].id);
        for(int i=1;i<=n;i++) ans+=a[i];
        multiset<int>aa;
        for(int i=1;i<=n;i++) aa.insert(a[i]);
        for(int i=1;i<=m;i++){
            if(b[i].id==0){
                ans-=b[i].val;
            }
            else{
                multiset<int>::iterator cur=aa.lower_bound(b[i].val);
                if(cur==aa.end()){
                    flag=false;
                    break;
                }
                ans-=(*cur);
                aa.erase(cur);
            }
        }
        if(flag==false){
            ans=0;
            int tot=0;
            for(int i=1;i<=m;i++){
                if(b[i].id==0){
                    cur[++tot]=b[i].val;
                }
            }
            sort(&cur[1],&cur[tot+1],cmp1);
            sort(&a[1],&a[n+1],cmp2);
            int pos=1;
            for(int i=1;i<=n&&pos<=tot;i++){
                if(a[i]>cur[pos]){
                    ans+=a[i]-cur[pos];
                    pos++;
                }
                else break;
            }
        } 
        printf("Case %d: %lld\n",cnt,ans);   
    }
    return 0;
}

J-Wheel of Fortune

K-The Magician

L-The Hanged Man

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值