• CF 1216


    看看蒟蒻交了一版才调完kk.png

    QQ截图20190922153857.png

    A

    链接

    Idea

    一道十分简单的题

    只需要在奇数点是判断下当前字符是否等于下一个字符

    1. 是。记录并修改
    2. 否。跳过

    Code

    int n,ans;
    char s[maxn];
    signed main(){
    	n=read(); scanf("%s",s+1);
    	for(int i=1;i<=n;i+=2){
    		if(s[i]==s[i+1]){ 
    			ans++;
    			if(s[i+1]=='b') s[i]='a';
    			else s[i]='b';
    		}
    	}
    	printf("%d
    ",ans);
    	printf("%s",s+1); 
        return 0;
    }
    

    B

    链接

    Idea

    考场上看到样例解释,他是从大的数开始算的。

    于是,我就排了个序。然后照着他的计算方法计算(ans)

    序列随便输出,然后。。。我就过了ts.png

    Code

    struct Node{
    	int id,val;	
    	inline bool operator<(const Node&x)const{return val>x.val;}
    }sum[maxn];
    int ans;
    signed main(){ 
    	int n=read();
    	for(int i=1;i<=n;i++){
    		sum[i].val=read();
    		sum[i].id=i;
    	}
    	sort(sum+1,sum+n+1);
    	for(int i=1;i<=n;i++)
    		ans+=(i-1)*sum[i].val+1;
    	printf("%d
    ",ans); 
    	for(int i=1;i<=n;i++)
    		printf("%d ",sum[i].id);
        return 0;
    }
    

    C

    链接

    Idea

    一道恶心的模拟,除了(if;else)就没啥了。看代码比较好理解,虽然我没有注释xyx.png

    QQ图片20190922160439.jpg

    Code

    signed main(){
    	int x1,y1,x11,y11;
    	int x2,y2,x22,y22;
    	int x3,y3,x33,y33;
    	int xr,yr,xrr,yrr;
        cin>>x1>>y1>>x11>>y11;
        cin>>x2>>y2>>x22>>y22;
        cin>>x3>>y3>>x33>>y33;
        if(x2<=x1&&x22>=x11){
            if(y2<= y1){
                if(y22>=y11) puts("NO");
                else
                    if(x3<=x1&&x33>=x11&&(y3<=y22||y3<=y1)&&y33>=y11) puts("NO");
                    else puts("YES");
            }else{
                if(y22>=y11){
                    if(x3<=x1&&x33>=x11&&y3<=y1&&(y33>=y2||y33>=y11)) puts("NO");
                    else puts("YES");
                }else{
                    if(x3<=x1&&x33>=x11&&y3<=y1&&y33>=y11) puts("NO");
                    else puts("YES");
                }
            }
        }else{
            if(y2<=y1&&y22>=y11){
                if(x2<=x1)
                    if(y3<=y1&&y33>=y11&&(x3<=x22||x3<=x1)&&x33>=x11) puts("NO");
                    else puts("YES");
                else{
                    if(x22>=x11)
                        if(y3<=y1&&y33>=y11&&(x33>=x2||x33>=x11)&&x3<=x1) puts("NO");
    					else puts("YES");
                    else
                        if(x3<=x1&&x33>=x11&&y3<=y1&&y33>=y11) puts("NO");
    					else puts("YES");
                    
                }
            }else
                if(x3<=x1&&x33>=x11&&y3<=y1&&y33>=y11) puts("NO");
    			else puts("YES"); 
        }
        return 0;
    }
    

    D

    链接

    Idea

    需要用到(Gcd),因为要求(n)个数的最大公约数,比(C)题还水

    注意(Gcd=0),开(long;long)就好了(sim)ka.png

    Code

    inline int gcd(int a,int b){
    	if(b==0) return a;
    	return gcd(b,a%b);
    }
    int n,a[maxn],b[maxn];
    signed main(){
    	n=read();
    	for(int i=0;i<n;i++) 
    		a[i]=read();
    	sort(a,a+n);
    	for (int i=1;i<n;i++) 
    		b[i]=a[i]-a[i-1];
    	int ans=b[0];
    	for(int i=1;i<n;i++)
    		ans=gcd(ans,b[i]);
    	int sum=0;
    	for(int i=0;i<n;i++) 
    		sum+=abs(a[n-1]-a[i]);
    	cout<<sum/ans<<' '<<ans;
        return 0;
    }
    

    E1

    链接

    Idea

    这道题。。。(POJ)上有。。。。ts.png

    我在这里放个博客链接
    再放上我的代码youl.png

    Code

    unsigned int sum[40000];
    int T,n;
    inline void play_table(){
        unsigned int pre=1,nw;
        sum[1]=1;
        for(int i=2;i<=32000;++i){
            nw=pre+(int)log10((double)i)+1;
            sum[i]=sum[i-1]+nw;
            pre=nw;
        }
    }
    inline int getd(int x){
        int k1;
        for(int i=1;i<=32000;++i)
            if(x<=sum[i]){
                k1=i;
                break;
            }
        int p=x-sum[k1-1],len=0,i;
        for(i=1;i<=k1;++i){
            len+=(int)log10((double)i)+1;
            if(p<=len)
                break;
        }
        int ilen=(int)log10((double)i)+1;
        len-=ilen;
        int k2=p-len;
        for(int j=k2+1;j<=ilen;++j)
            i/=10;
        return i%10;
    }
    signed main(){
        play_table();
    	T=read();
        while(T--){
            n=read(); 
            printf("%lld
    ",getd(n));
        }
        return 0;
    }
    

    E2

    链接

    Idea

    (E1)(int)范围,(E2)(long;long)范围ts.png

    这里我用到二分来解决,不多,也就三四十行cy.png

    Code

    inline int countDigits(int n){//数字位数 
        int cnt=0;
        while(n>0){
            n/=10;
            cnt++;
        }
        return cnt;
    }
    inline int getPos(int a){
        int l=countDigits(a);
        int res=0;
        for(int i=0;i<l-1;i++)
            res=res*10+9;
        int offset=0;
        int prev=a,curr=res;
        int ans=0;
        while(prev>0){
            int d=prev-curr;
            ans+=(d*(d+1)/2+offset*d)*l;
            offset+=d;
            l--;
            prev=curr;
            curr/=10;
        }
        return ans;
    }
    inline int getPosv2(int a){
        int l=countDigits(a);
        int res=0;
        for(int i=0;i<l-1;i++)
            res=res*10+9;
        int prev=a,curr=res;
        int ans=0;
        while(prev>0){
            ans+=(prev-curr)*l;
            l--;
            prev=curr;
            curr/=10;
        }
        return ans;
    }
    int k;
    signed main(){
        int T=read();
        while(T--){
            int k=read();
            int l=1,r=1e9;
            while(l<r){
                int mid=(l+r+1)>>1;//(l+r+1)/2;
                int val=getPos(mid);
                if(val>k) r=mid-1;
                else l=mid;
            }
            int d=k-getPos(l);
            if(d==0){
                cout<<l%10<<endl;
                continue;
            }
            r=l+1,l=1;
            while(l<r){
                int mid=l+r>>1; //l+r/2;
                int val=getPosv2(mid);
                if(val<d) l=mid+1;
                else r=mid;
            }
            int z=getPosv2(l)-d;
            int ans=0;
            while(z>=0){
                ans=l%10;
                l/=10;
                z--;
            }
            cout<<ans<<endl;
        }
    	return 0;
    }
    

    F

    链接

    Idea

    这里我用的是(DP)

    这一题其实观察题目的性质,选择位置 (i) 的代价为
    (i),也就是说代价随着位置增加

    发现到这里有单调性,考虑利用单调性 (DP)

    (f[i]) 表示把 (1)(i) 覆盖的最小代价

    然后预处理出 (g[i]) 表示从 (i) 位置往右的第一个 (1) 的位置

    (g) 的预处理显然,考虑 (f[i]) 怎么转移

    首先我们可以选择 (i) 位置,那么转移显然

    然后考虑 (i) 本身不选,选择一个位置(j) ,使得 (j) 能够覆盖 (i)

    显然我们考虑选择的位置为 (g[i−k]) (这里先不考虑 (i−k<1) 的情况)

    意思就是说,选择位置 (i−k) 往右的第一个 (1) 位置(也就是最左边能够覆盖 (i)(1)

    我们设这个位置为 (c),考虑选择位置 (c) 的最小花费,因为 (f) 单调不减,最小花费即为 (f[c−k−1]+c)

    发现其实我们直接贪心地选择位置 (c) 一定比选择 (c) 后面的某个 (1) 更优

    因为考虑后面位置代价,首先选后面本身位置的代价就比选 (c) 大,其次选后面的话,我们最优的(f)也会变大

    所以后面的一定不如位置 (c),我们直接选择位置 (c) 转移即可

    记住开(long ; long),否则就挂lb.png

    Code

    int f[maxn],dp[maxn];
    char s[maxn];
    int n,k;
    signed main(){ 
    	n=read(); k=read();
    	scanf("%s",s+1);
    	f[n+1]=3*n;
    	for(int i=n;i>=1;i--) f[i]=s[i]=='1'?i:f[i+1];
    	dp[0]=0;
    	for(int i=1;i<=n;i++){
    		dp[i]=dp[i-1]+i;
    		int cnt=f[max(i-k,1ll)];
    		if(cnt<=i+k)
    			dp[i]=min(dp[i],dp[max(cnt-k,1ll)-1]+cnt);
    	}
    	printf("%lld",dp[n]);
        return 0;
    }
    

    [The quad END ]

    fx.gif

    不要问图片为什么这么快,我也不知道youl.pngyoul.png

    ( ext{千万不要对任何事感到后悔,因为它曾经一度就是你想要的.后悔没用,要么忘记,要么努力})

  • 相关阅读:
    【转载】使用缓存的9个误区(上)
    .NET开发者必备的工具箱(转载)
    Java基础之反射(一)
    【干货转载】.NET中的六个重要概念:栈、堆、值类型、引用类型、装箱和拆箱
    CKEditor配置详解
    ASP.NET中IsPostBack的理解
    三层架构与设计模式思想部署企业级数据库业务系统开发
    AppDomain 详解(转)
    字符串基础总结
    访问数据库的时候报错 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
  • 原文地址:https://www.cnblogs.com/cbyyc/p/11566060.html
Copyright © 2020-2023  润新知