zoukankan      html  css  js  c++  java
  • hut_csust 训练赛第三场 解题报告

    题目链接: www.acmore.net

    Problem A

      遍历数组a, 对于每一个元素 a[i], 统计区间 ( a[i], a[i]+d ] 有X个点,则符合条件的为 C(2,X) 

      累加就可以了

    解题代码

    View Code
    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<map>
    using namespace std;
    
    
    typedef long long LL;
    const int N = 1e5+10;
    const int M = 1e6;
    map< LL, int > Mp;
    
    
    int n, C[M+10], size;
    LL a[N], d, b[M];
    void update( int x )
    {
        for(; x <= M; x += (x&(-x)) )
                C[x] += 1; 
    }
    int read( int x )
    {
        int res = 0;
        for( ; x >= 1; x -= (x&(-x))  )
            res += C[x];
        return res;
    }
    int main()
    {
        while( scanf("%d%lld", &n, &d) != EOF)
        {
            Mp.clear();
            size = 0;    
            for(int i = 0; i < n; i++ )
            {
                scanf("%lld", &a[i]);
                b[size++] = a[i];
                b[size++] = a[i]+d;
            }        
            sort( b, b+size );
            size = unique( b, b+size) - b;
            int tmp = 1;
            for(int i = 0; i < size; i++)
                Mp[ b[i] ] = tmp++;
    
            memset( C, 0, sizeof(C));
            for(int i = 0; i < n; i++)
                update( Mp[ a[i] ] );
            LL ans = 0;    for(int i = 0; i < n; i++)
            {
                int k = read( Mp[ a[i]+d ] ) - (i+1);    
                if( k > 1 )    
                    ans += 1LL*k*(k-1)/2;
            }
            printf("%lld\n", ans );    
        }
        return 0;
    }

    Problem B

      字符串处理,取最长的,当有多个,则字典序最大的是结果

    解题代码

    View Code
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<vector>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    char str[110][110];
    
    vector< string > S;
    int main()
    {
        int n;
        while( scanf("%d", &n) != EOF )
        {
            int L = 0;
            for(int i = 0; i < n; i++)
            {
                scanf("%s", str[i] );
                if( strlen( str[i] ) > L ) 
                    L = strlen(str[i]);
            }
            S.clear();    
            for(int i = 0; i < n; i++)
                if( strlen(str[i]) == L ) 
                        S.push_back( str[i] );
            sort( S.begin(), S.end() );    
            printf("%s\n", (S[ S.size()-1 ]).c_str() );
        }
        return 0;
    }

    Problem C

      递推, F(N) = F(N-1)+ F(N-2)

    解题代码

    View Code
    #include<stdio.h>
    
    typedef long long LL;
    
    LL f[55] = {1,1,2};
    
    int main()
    {
        for(int i = 3; i <= 50; i++)
                f[i] = f[i-1]+f[i-2];
        int a, b, T;
        scanf("%d", &T);
        while( T-- && scanf("%d%d", &a,&b) )
            printf("%lld\n", f[b-a] );
        return 0;
    }

    Problem D

      枚举长度O(N),之后枚举左边界O(N), 使用差值取模O( LogN ) 判定, 总时间复杂度为 O( N*N*LogN)

    解题代码

    View Code
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    
    typedef unsigned long long LL;
    
    char s1[1010];
    int n;
    LL A[1010],B[1010], C[2][2020], T[1010];
    
    
    void add(int key, int x, LL val )
    {
        for(; x <= 1000; x+=(x&(-x)))
                C[key][x] += val;
    }
    LL read(int key, int x)
    {
        LL res = 0;
        for(; x >= 1; x -= (x&(-x)) )
            res += C[key][x];
        return res;
    }
    void init()
    {
        A[0] = B[0] = 0;
        for(int i = 1; i <= n; i++)
        {
            A[i] = (s1[i]-'a'+1)*T[i-1];    
            B[i] = (s1[n+1-i]-'a'+1)*T[i-1];
        }    
        memset( C, 0, sizeof(C));
        for(int i = 1; i <= n; i++)
        {
            add( 0, i, A[i] );
            add( 1, i, B[i] );
        }
    }
    int find( int len )
    {
        for(int i = 1; i+len-1 <= n; i++ )
        {
            int a = i, b = i+len-1;    
            int c = (n+1)-b, d = (n+1)-a;    
            LL sa = read(0,b)-read(0,a-1);
            LL sb = read(1,d)-read(1,c-1);
            sa *= T[c-1]; sb *= T[a-1];
            if( sa == sb )     return i;
        }
        return -1;
    }
    int main()
    {
        T[0] = 1;
        for(int i = 1; i <= 1010; i++)
            T[i] = T[i-1]*27;
    
        while( scanf("%s", s1+1) != EOF)
        {
            n = strlen(s1+1);    
            
            init();    
            for(int m = n; m >= 1; m-- )
            {
                int s = find(m);    
                if( s != -1 )
                {
                    for(int i = s; i < s+m; i++)
                        printf("%c", s1[i]); puts("");
                    break;
                }    
            }
        }
        return 0;
     }

    Problem E

      按分数排序

    解题代码

    View Code
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<stdlib.h>
    using namespace std;
    
    const int N = 5150;
    struct node
    {
        char name[30];
        double score;
        bool operator < ( node tmp ) const
        {
            return score > tmp.score;    
        }
        void read( )
        {
                scanf("%s %lf", name, &score );    
        }
    }stu[N];
    
    int n, r;
    char str[30];
    
    int main()
    {
        while( scanf("%d", &n) !=EOF)
        {
            for(int i = 0; i < n; i++)
                stu[i].read();
            sort( stu, stu+n );
            
            scanf("%d", &r);
            while( r-- )
            {
                scanf("%s", str );    
                for(int i = 0; i < n; i++)
                    if( strcmp( stu[i].name, str ) == 0 )
                    {
                        printf("%d\n", i+1);
                        break;
                    }
            }    
        }
        return 0;
    }

    Problem F

      BFS广搜即可,因为每个点至多走一次,也才10*10. 注意起点也算1步

    解题代码

    View Code
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<iostream>
    #include<queue>
    using namespace std;
    
    
    
    char map[15][15];
    int n, m, s;
    int vis[15][15];
    struct node
    {
        int x, y;
        int step;
    }info,nxt;
    
    bool legal(int x, int y)
    {
        if( x >= 1 && x <= n && y >= 1 && y <= m )
            return true;
        return false;
    }
    void getdir( int x1, int y1, int &x, int &y )
    {
        switch( map[x1][y1] )
        {
            case 'W': 
                x = x1;
                y = y1-1;
                break;
            case 'E':
                x = x1;
                y = y1+1;
                break;
            case 'N':
                x = x1-1;
                y = y1;
                break;
            case 'S':
                x = x1+1;
                y = y1;
                break;
        }
    }
    queue<node> Q;
    void solve()
    {
        memset( vis , 0, sizeof(vis) );
        while( !Q.empty() ) Q.pop();
        info.x = 1; info.y = s;
        info.step = 1;
        Q.push(info);
        vis[info.x][info.y] = 1;
        while( !Q.empty() )
        {
            info = Q.front(); Q.pop();
            
                int x, y;
                getdir( info.x,info.y,x,y);    
                if( !legal(x,y) )
                {
                    printf("%d step(s) to exit\n",info.step);     
                    return;    
                }
                else if( vis[x][y] )
                {
                    printf("%d step(s) before a loop of %d step(s)\n", vis[x][y]-1, info.step-vis[x][y]+1);
                    return;    
                }
                else
                {
                    vis[x][y] = info.step+1;
                    nxt.step = info.step+1;
                    nxt.x = x; nxt.y = y;
                    Q.push(nxt);    
                }
        }
    }
    int main()
    {
        while( scanf("%d%d%d", &n, &m, &s) != EOF)
        {
            if( !(n+m+s) ) break;    
            for(int i = 1; i <= n; i++)
                scanf("%s", map[i]+1);
            solve();
        }
        return 0;
    }

    Problem G

      位运算,异或, 当都为1时才为1,否则为0 

      初始令X = 0, 与所有数异或,那么相同的数,偶数个后都会为0,剩下的就是奇数个的值

      注意,后台数据貌似没有 N=0,所以结束条件为 EOF,否则会TLE

    解题代码

    View Code
    #include<stdio.h>
    
    int main()
    {
        int n;
        while( scanf("%d", &n) != EOF )
        {
            if( n == 0 ) break;    
            int a, x = 0;
            for(int i = 1; i <= n; i++)
            {    scanf("%d", &a); x ^= a; }
            printf("%d\n", x);    
        }
        return 0;
    }

    Problem H

      11年网络赛立体空间的简单版.

      枚举两个水果成直线,然后扫其他水果. 利用叉积判定是否在直线上.

      注意 坐标为 double类型. WA在了这上面

    解题代码

    View Code
    #include<stdio.h>
    #define max(x,y) (x)>(y)?(x):(y)
    #define min(x,y) (x)<(y)?(x):(y)
    const int inf=0x7fffffff;
    typedef long long LL;
    
    struct node      // Fruit
    {
        double x,y;     
        void read( )
        {
            scanf("%lf%lf", &x,&y);
        }
    }Q[1010];
    
    const double esp = 1e-8;
    int sign(double x )
    {
        return (x<-esp)? -1 : (x>esp);
    }
    bool judge( double x1,double y1,double x2,double y2,double x,double y )
    {
             if( ( sign( ( x1-x )*( y2-y ) - ( x2-x )*( y1-y ) )) == 0 )
                    return true;
             return false;
    }
    int n;
    
    int main()
    {
        int T;
        scanf("%d", &T);
        for(int Case = 1; Case <= T; Case++ )    
        {
            scanf("%d", &n);
            int ans = 1;
            for(int i = 0; i < n; i++)
                Q[i].read();
            for(int i = 0; i < n; i++)
                for(int j = i+1; j < n; j++)
                {
                    int cnt = 2;    
                    for(int k = j+1; k < n; k++)
                    {
                        if( judge( Q[i].x, Q[i].y, Q[j].x, Q[j].y, Q[k].x, Q[k].y ) )
                            cnt++;
                    }
                    ans = max( ans, cnt );    
                }
            printf("Case %d: %d\n",Case, ans );    
        }
        return 0;
    }

    Problem I

      按要求使用栈模拟即可.

    解题代码

    View Code
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<iostream>
    using namespace std;
    
    stack<string> s1, s2;
    
    string op, web, cur;
    int main()
    {
        int Case = 1;
        while( cin>>op )
        {
            while( !s1.empty() ) s1.pop();
            while( !s2.empty() ) s2.pop();
            printf("Case %d:\n", Case++);
            cur = "http://www.acmore.net/"; 
            cout << cur << endl;    
            while( cin>>op )
            {
        //        cout << "op = " << op << endl;    
                if( op == "end" )
                {
                    cout << "end" << endl;    
                    break;
                }    
                else if(  op ==  "visit"   )
                {
                    cin >> web;    
        //            cout << "web = " << web << endl;    
                    while( !s2.empty() ) s2.pop();    
                    s1.push( cur );
                    cur = web;    
                    cout << cur << endl;    
                }
                else if(  op == "back" )
                {
                    if( !s1.empty()  )
                    {
                        s2.push( cur );
                        cur = s1.top(); s1.pop(); 
                        cout << cur << endl;    
                    }
                    else
                        cout << "This is the first page" << endl;
                }
                else if(  op == "forward" )
                {
                    if( !s2.empty() )
                    {
                        s1.push( cur );
                        cur = s2.top(); s2.pop();
                        cout << cur << endl;    
                    }
                    else
                        cout << "This is the last page" << endl;
                }
            }
        }
        return 0;
    }

    Problem J

      模拟题.....

    解题代码 

    View Code
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    using namespace std;
    
    int num[10];
    char G[1000][1000];
    
    int main() {
        int N, M;
        while (scanf("%d %d", &N, &M), N|M) {
            memset(num, 0, sizeof (num));
            for (int i = 0; i <= N*5; ++i) {
                scanf("%s", G[i]);
            }
            for (int i = 0; i < N; ++i) {
                for (int j = 0; j < M; ++j) {
                    int cnt = 0;
                    int l = i*5+1, r = i*5+4, u = j*5+1, d = j*5+4; 
                    for (int p = l; p <= r; ++p) {
                        for (int q = u; q <= d; ++q) {
                            if (G[p][q] == '*') {
                                ++cnt; 
                            }
                        }
                    }
                    num[cnt/4]++;
                }
            }
            for (int i = 0; i < 5; ++i) {
                printf(i == 0 ? "%d" : " %d", num[i]); 
            }
            puts("");
        }
        return 0; 
    }

      

  • 相关阅读:
    链队列的实现
    LeetCode——Count Complete Tree Nodes
    LeetCode——Lowest Common Ancestor of a Binary Search Tree
    LeetCode——Palindrome Linked List
    中文乱码问题及其解决办法
    LeetCode——Valid Anagram
    TCP/IP网络知识点总结
    深入理解javascript原型和闭包——从【自由变量】到【作用域链】
    AJAX笔试面试题汇总
    前端开发面试知识点大纲
  • 原文地址:https://www.cnblogs.com/yefeng1627/p/2846507.html
Copyright © 2011-2022 走看看