• WAhaha_hnu (zoj 2010 oct月赛)


    官方解题报告 http://blog.watashi.ws/1515/zojmonthly1010/

    A题  签到题,╮(╯▽╰)╭,因为 int -> char* 错了一次,还是很粗心。

    View Code
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<string>
    
    using namespace std;
    
    const int N = 101100;
    char str[N];
    
    
    bool isch( char ch ){
        if( (ch>='a'&&ch<='z') || (ch>='A'&&ch<='Z') )
            return true;
        return false;
    }
    string get_str( int x ){
        
        string tmp;
        char sa[1010];    
        int len = 0;
        while( x ){
            sa[len++] = x%10 + '0'; x /= 10;
        }
        for(int i = len-1; i >= 0; i-- )
            tmp += sa[i];
        return tmp;
    }
    int main(){
        while( gets( str) ){
            if( strcmp( str, "EOF" ) == 0 ) break; 
    
            //printf("str = %s", str );    
            int len = strlen(str), n = 0, i = 0;
            string s;    
            
            while( i < len )    
            {
                if( isch( str[i] ) ){
    
                    s += str[i];
    
                    int t = i+1;
                    while( isch(str[t]) && (t<len) ) ++t;
                    t--;
    
                    if( t-i >= 1 ){
                        if( t-i >= 2 )    
                            s += get_str( t-i-1 );
                        s += str[t];    
                    }    
                    i = t+1;    
                }    
                else    s += str[i++];
            }
            printf("%s\n", s.c_str() );    
        }
        return 0;
    }

    B题  一开始理解错题意,粗心一路到底啊~~

      假设横切为x,纵切为y,克隆为a, 则对于总分数n,以及操作次数m,共有

        2*x*(y+1) + a = n

        x + y + a = m 

      两式联立可得 x, y 的计算式, 因为 n,m 都比较大, 但是 x*y <= n => x <= sqrt(n) || y <= sqrt(n)

      所以我们可以通过分别枚举 x,y 到sqrt(n) 来得出结果, 因为 x,y对称,所以可以在一个循环内得出。

      另外,以上两式的成立条件是在 x > 0 的前提下, 所以当 x = 0,时候要特判,还有当 n <= m 时也要特判。

    View Code
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    #define MIN(a,b) (a)<(b)?(a):(b)
    typedef long long LL;
    
    int main(){
    
        int n, m, T;
        scanf("%d", &T);
    
        while( T-- )
        {
            scanf("%d %d", &n,&m);
            if( n <= m ){
                printf("-1\n");
                continue;
            }    
            if( n-1 == m ){
                printf("0\n");
                continue;
            }    
            bool flag = false;
            int res = m+1;
            int Max = sqrt(n)+1;    
            for(int x = 0; x <= Max; x++ )
            {
                int ta = n-m-x, tb = 2*x-1;    
                if( ta%tb == 0 ){
                    int y = ta/tb;
                    if( (y>=0) && (x+y<=m) ){    
                        flag = true;    
                        res = MIN( res, m-x-y );    
                    }    
                }
                ta = n-m+x; tb = 2*x+1;
                if( ta%tb == 0 ){
                    int y = ta/tb;
                    if( (y >=0) && (x+y<=m) ){
                        flag = true;
                        res = MIN( res, m-x-y);
                    }
                }
            }    
            if( flag )  printf("%d\n", res );
            else    printf("-1\n");
        }
        return 0;
    }

    E题 看题后第一眼想到DP, 但是时间复杂度无法承受,然后就没管了,回头细想下,觉得贪心应该还是能过的... 越学越笨了~~~

      题目未限定通过陷阱顺序, 通过将陷阱按照 D 排序后, 依次处理,若累积时间 T <= Di 则拆除过去,否则失血,此时选择 [1,i]区间

    中时间消耗最大的,这里使用优先队列 来维护。

    View Code
    #include<iostream>
    #include<cstdio>
    #include<cstring> 
    #include<queue>
    #include<algorithm>
    using namespace std;
    const int N = 25010;
    
    pair<int,int> p[N];
    
    int n, k;
    
    int main(){
        while( scanf("%d%d", &n,&k) != EOF)
        {
            for(int i = 0; i < n; i++)
                scanf("%d%d", &p[i].second,&p[i].first );
            sort( p, p+n );
            int T = 0, hp = 0;
            priority_queue< int > Q;
            
            for(int i = 0; i < n; i++ ){
                T += p[i].second;
                Q.push( p[i].second );
                while( T > p[i].first ){
                    T -= Q.top(); Q.pop();
                    hp++;
                }    
            }
            if( hp < k ) printf("%d\n", hp );
            else printf("-1\n");
        }
        return 0;    
    }

    I题 ╮(╯▽╰)╭,比赛时看题能力还是不够,错把题目看成是 折现上的点 相邻的直接距离了。

      计算折线总长度后,得到点间距离,然后从起点开始模拟查找就可以得出结果了。

  • 相关阅读:
    iOS-runtime-根据协议名调某一个类有与协议里面放的相同的方法
    Mac下显示隐藏文件
    OC开发_整理笔记——多线程之GCD
    兵器簿之cocoaPods的安装和使用
    手写代码UI,xib和StoryBoard间的的优劣比较
    OC开发_Storyboard——MapKit
    smartFloat
    固定浮动侧边栏(SmartFloat)
    一个模拟时钟的时间选择器 ClockPicker
    分布式事务TransactionScope
  • 原文地址:https://www.cnblogs.com/yefeng1627/p/2969961.html
Copyright © 2020-2023  润新知