ACM-ICPC 2018 沈阳赛区网络预赛 D A*算法 G I 模拟 K讨论

版权声明:本文为博主原创文章,未经博主允许也可以转载。 https://blog.csdn.net/FrankAx/article/details/82555817

D
题意:找是否存在第k短路且判断长度是否小于等于T。
思路:A*算法裸题。

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int AX = 1e5+66;
const int MAXN = 1e4+66;
int n , m , k;
int s ,t ;
int tot ;
int retot ;
struct edge{
    int to , w ;
    int next1;
}G[AX] , RG[AX];
//f = g + h 
struct Node{
    int v;
    int f , h , g;
    bool operator < ( const Node &a ) const{
        if( f == a.f ){
            return g > a.g;
        }
        return f > a.f;
    }
};

int dis[MAXN];
int head[MAXN];
int rehead[AX];
int vis[MAXN];
void addedge( int u , int v , int c ){
    G[tot].to = v;
    G[tot].w = c;
    G[tot].next1 = head[u];
    head[u] = tot++;

    RG[retot].to = u;
    RG[retot].w = c;
    RG[retot].next1 = rehead[v];
    rehead[v] = retot ++;
}
void SPFA(){
    for( int i = 1 ; i <= n ; i++ ){
        dis[i] = INF;
    }   
    dis[t] = 0;
    queue<int>Q;
    Q.push(t);
    while( !Q.empty() ){
        int u = Q.front();
        Q.pop();
        for( int i = rehead[u] ; ~i ; i = RG[i].next1 ){
            int v = RG[i].to ;
            int w = RG[i].w ;
            if( dis[v] > dis[u] + w ){
                dis[v] = dis[u] + w;
                Q.push(v);
            }
        }
    }   
}

int Astar( Node a ){
    memset( vis , 0 ,sizeof(vis) );
    if( dis[s] == INF ) return -1;
    if( s == t ) k++;
    priority_queue<Node>Q;
    Q.push(a);
    while( !Q.empty() ){
        Node tmp = Q.top();
        Q.pop();
        int v = tmp.v;
        vis[v] ++ ;
        if( vis[t] == k ) return tmp.g;
        for( int i = head[v] ; ~i ; i = G[i].next1 ){
            Node p;
            p.v = G[i].to;
            p.h = dis[G[i].to];
            p.g = tmp.g + G[i].w;
            p.f = p.g + p.h;
            Q.push(p);
        }
    }
    return -1;
}

int main(){
    int T;
    while( ~scanf("%d%d",&n,&m) ){
        scanf("%d%d%d%d",&s,&t,&k,&T);
        tot = 0 ;
        retot = 0;
        memset( head , -1 , sizeof(head) );
        memset( rehead , -1 , sizeof(rehead) );
        int x , y , w ;
        for( int i = 0 ; i < m ; i++ ){
            scanf("%d%d%d",&x,&y,&w);
            addedge( x , y , w );
        }
        SPFA();
        Node a;
        a.v = s ;
        a.g = 0;
        a.h = dis[s];
        a.f = a.g + a.h;
        int g = Astar(a);
    //printf("%d\n",g);
        if( g != -1 && g <= T ){
            printf("yareyaredawa\n");
        }else{
            printf("Whitesnake!\n");
        }
    } 
    return 0 ;
}

I
思路:模拟,16进制转2进制,然后奇偶校验,然后根据映射得出结果。
Code:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define LL long long 
using namespace std;
map<char,string> mp; 
map<string , int > mp1; 
void init(){
    mp['0'] ="0000"; mp['1']="0001";mp['2']="0010";mp['3']="0011";mp['4']="0100";mp['5']="0101";mp['6']="0110";mp['7']="0111";mp['8']="1000";mp['9']="1001";mp['A']="1010";mp['B']="1011";mp['C']="1100";mp['D']="1101";mp['E']="1110";mp['F']="1111";
    mp['a']="1010";mp['b']="1011";mp['c']="1100";mp['d']="1101";mp['e']="1110";mp['f']="1111";
}
int main(){
    int T;
    init();
    ios_base::sync_with_stdio(false);
    cin.tie(0) ; cout.tie(0) ; 
    cin >> T;
    int m , n ; 
    while( T-- ){
        string a; 
        string b; 
        string c; 
        cin >> m >> n ; 
        mp1.clear();
        int asc ;
        string s ;  
        for( int i = 0 ; i < n ; i++ ){
            cin >> asc >> s ; 
            mp1[s] = asc ; 
        }
        b = "";
        cin >> a ; 
        int len = a.size();
        for( int i = 0 ; i < len ; i++ ){
            b += mp[a[i]];
        }
        len = b.size();
        for( int i = 0 ; i + 8 < len ; i += 9 ){
            int num = 0 ; 
            string tmp = "" ;
            int j ; 
            for( j = i ; j < i + 8 ; j++ ){
                if( b[j] == '1' ){
                    num ++ ; 
                }
                tmp += b[j] ; 
            }
            if( num % 2 ){
                if( b[j] == '0' ) c += tmp ; 
            }else{
                if( b[j] == '1' ) c += tmp ; 
            }
        }
        int size = c.size() ; 
        string tmp = "" ; 
        string res = "" ;
        int length = 0 ;
        for( int i = 0 ; i < size ; i ++ ){
            tmp += c[i] ; 
            if( length == m ) break ; 
            if( mp1[tmp] ){
                //cout << (char)mp1[tmp];
                res += (char)mp1[tmp];
                length ++ ;
                tmp = "";
            }
        }
        cout << res << endl;
    }   
    return 0 ;
}

K
题意:一个数为素数且任意子串为素数
思路:考虑到答案中任意一位都必须是1或质数,可知答案只可能由1、2、3、5、7构成。由于任意两个不为1的数字构成 的两位数一定可以被11整除,所以答案中除1外的数字只能出现一次;1最多出现2次,因为111可以被3整除;而 2、5、7三者一定不会有两者同时出现。因此满足条件的整数不会超过四位,全部预处理出来即可。
Code:

#include <bits/stdc++.h>
using namespace std;

int a[21]={1,2,3,5,7,11,13,17,23,31,37,53,71,73,113,131,137,173,311,317,10000};

int init(string s){
    int cnt = 0;
    for(int i=0;i<s.length();i++){
        cnt = cnt*10 + s[i]-'0';
    }
    return cnt;
}
int t;
int main(){
    cin>>t;
    for(int i=1;i<=t;i++){
        string s;
        cin>>s;
        cout<<"Case #"<<i<<": ";
        if(s.length()>=4){
            cout<<"317"<<endl;
        }else{
            int ans = init(s);
            for(int i=0;i<21;i++){
                if(a[i]>ans){
                    cout<<a[i-1]<<endl;
                    break;
                }
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/FrankAx/article/details/82555817
今日推荐