zoukankan      html  css  js  c++  java
  • Topcoder SRM 583 DIV2 解题报告

    -----------------

    250 SwappingDigits

    给一个数字串,要求交换两个数字的位置得到一个尽可能小的数字。(可以不交换)

    ----

    从高位向低位枚举,对每一位,从低位向高位找一个比它小的数,若能找到则交换即答案。

    对首位不能为0进行特殊处理。

    #include <iostream>
    #include <string>
    #include <algorithm>
    
    using namespace std;
    
    class SwappingDigits{
        private:
        public:
            string minNumber(string num)
            {
                int n=num.length();
                int p;
                for (int i=0;i<n;i++)
                {
                    p=i;
                    for (int j=n-1;j>i;j--)
                        if (num[j]<num[p]&&(i!=0||num[j]!='0')) p=j;
                    if (p!=i){
                        swap(num[i],num[p]);
                        break;
                    }
                }
                return num;
            }
    };
    -----------------

    550 IDNumberVerification

    判断一个18位的身份证号是否合法,并输出性别。

    ----

    直接模拟即可。注意sequential code不能为000。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <vector>
    using namespace std;
    
    const int day12[13]={ 0,31,28,31,30,31,30,31,31,30,31,30,31 };
    const int lday12[13]={ 0,31,29,31,30,31,30,31,31,30,31,30,31 };
    
    class IDNumberVerification{
        private:
            int tonum(string s){
                int ret=0;
                int len=s.length();
                for (int i=0;i<len;i++) ret=ret*10+s[i]-'0';
                return ret;
            }
            int cmpday(int y1,int m1,int d1,int y2,int m2,int d2){
                if (y1==y1&&m1==m2&&d1==d2) return 0;
                if (y1>y2) return 1;
                if (y1==y2&&m1>m2) return 1;
                if (y1==y2&&m1==m2&&d1>d2) return 1;
                return -1;
            }
            bool isleap(int year){
                if ( (year%4==0&&year%100!=0)||(year%400==0) ) return true;
                return false;
            }
            bool isdate(int y,int m,int d){
                if (y<1900||y>2011) return false;
                if (m>12||m<1) return false;
                if (d<1) return false;
                if (!isleap(y)){
                    if (d>day12[m]) return false;
                }
                else if (d>lday12[m]) return false;
                return true;
            }
            bool getx(string id){
                long long a=0;
                long long bit=1;
                for (int i=17;i>=0;i--){
                    if (id[i]=='X') a+=10*bit;
                    else a+=(id[i]-'0')*bit;
                    bit*=2;
                }
                if (a%11==1) return true;
                return false;
            }
        public:
            string verify(string id, vector<string> regionCodes)
            {
                bool find;
                string male="Male";
                string female="Female";
                string invalid="Invalid";
                string region=id.substr(0,6);
                string birthday=id.substr(6,8);
                string sequential=id.substr(14,3);
                string checksum=id.substr(17,1);
                int year=tonum(birthday.substr(0,4));
                int month=tonum(birthday.substr(4,2));
                int day=tonum(birthday.substr(6,2));
                find=false;
                int siz=regionCodes.size();
                for (int i=0;i<siz;i++)
                    if (regionCodes[i]==region){
                        find=true;
                        break;
                    }
                if (!find) return invalid;
                if (!isdate(year,month,day)) return invalid;
                if (cmpday(year,month,day,1900,1,1)<0||
                    cmpday(year,month,day,2011,12,31)>0) return invalid;
                if (!getx(id)) return invalid;
                if (sequential=="000") return invalid;
                if (tonum(sequential)&1) return male;
                else return female;
            }
    };
    
    -----------------

    900 GameOnABoard

    有一个由0和1组成的n*m的棋盘,A从中选一个点,B从中选一个点,两点间最短数字和为L。

    A要使L最小,B要使L最大。双方都足够聪明。

    ----

    直接n*m次最短路居然木有超时。。。这不科学。。。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <queue>
    using namespace std;
    
    const int INF=1e9+7;
    const int maxm=111111;
    const int maxn=11111;
    const int direct[4][2]={ {0,1},{1,0},{-1,0},{0,-1} };
    
    struct EDGENODE{
        int to;
        int next;
        int w;
    };
    
    class CSPFA{
    private:
        EDGENODE edges[maxm];
        int head[maxn],edge,node;
        bool visit[maxn];
        int outque[maxn];
        queue<int>que;
    public:
        int dist[maxn];
        void addedge(int u,int v,int c){
            edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
            //edges[edge].w=c,edges[edge].to=u,edges[edge].next=head[v],head[v]=edge++;
        }
        void init(int n){
            memset(head,-1,sizeof(head));
            edge=0;
            node=n;
        }
        bool SPFA(int src)
        {
            int top;
            for (int i=0;i<=node;i++) dist[i]=INF;
            memset(visit,0,sizeof(visit));
            memset(outque,0,sizeof(outque));
            while (!que.empty()) que.pop();
            que.push(src);
            visit[src]=true;
            dist[src]=0;
            while (!que.empty()){
                top=que.front();
                que.pop();
                visit[top]=false;
                outque[top]++;
                if (outque[top]>node) return false;
                for (int k=head[top];k!=-1;k=edges[k].next)
                {
                    if ( dist[edges[k].to]==INF||dist[edges[k].to]>dist[top]+edges[k].w )
                    {
                        dist[edges[k].to]=dist[top]+edges[k].w;
                        if (!visit[edges[k].to])
                        {
                            visit[edges[k].to]=true;
                            que.push(edges[k].to);
                        }
                    }
                }
            }
            return true;
        }
        int max_short_path(int u)
        {
            int ans=0;
            SPFA(u);
            for (int i=0;i<node;i++) ans=max(ans,dist[i]);
            return ans;
        }
    };
    
    
    class GameOnABoard{
    private:
        CSPFA sol;
        int n,m;
        bool xycheck(int x,int y){
            if (x>=0&&x<n&&y>=0&&y<m) return true;
            return false;
        }
    public:
        int optimalChoice(vector<string> cost)
        {
            int ans;
            n=cost.size();
            m=cost[0].size();
            sol.init(n*m);
            for (int i=0;i<n;i++)
            {
                for (int j=0;j<m;j++)
                {
                    for (int k=0;k<4;k++)
                    {
                        int x=i+direct[k][0];
                        int y=j+direct[k][1];
                        if (xycheck(x,y)) sol.addedge(i*m+j,x*m+y,cost[x][y]-'0');
                    }
                }
            }
            ans=INF;
            for (int i=0;i<n;i++)
            {
                for (int j=0;j<m;j++)
                {
                    int t=cost[i][j]-'0';
                    ans=min(ans,sol.max_short_path(i*m+j)+t);
                }
            }
            return ans;
        }
    };
    
    -----------------


  • 相关阅读:
    题解 P3717 【[AHOI2017初中组]cover】
    【题解】 [POI2012]FES-Festival (差分约束)
    【题解】 [HNOI2005]狡猾的商人(差分约束)
    【题解】 [SCOI2011]糖果 (差分约束)
    【题解】 POJ 1201 Intervals(差分约束)
    【题解】 Codeforces 919F A Game With Numbers(拓扑排序+博弈论+哈希)
    【题解】 [ZJOI2012]灾难 (拓扑排序+LCA)
    【题解】 [HAOI2016]食物链 (拓扑排序)
    【题解】 Luogu P1402 酒店之王 (二分图匹配)
    【题解】 [NOI2009]变换序列 (二分图匹配)
  • 原文地址:https://www.cnblogs.com/cyendra/p/3226284.html
Copyright © 2011-2022 走看看