Codeforces Round #290 (Div. 2) C. Fox And Names && D. Fox And Jumping

题意:

给你N个字符串,让你重新编写字典序,使得这N个字符串按照字典序排列

解题思路:

相邻的两个字符串直接相互比较,可以得出某些字母一定要在某些字母前面,让人联想到拓扑排序

因此建图,进行拓扑排序

注意:当前面全部相同的时候,长度大的排在后面是不行的,需要特判,这里wa了几次

//      whn6325689
//		Mr.Phoebe
//		http://blog.csdn.net/u013007900
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#include <functional>
#include <numeric>
#pragma comment(linker, "/STACK:1024000000,1024000000")


using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef vector<int> vi;

#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lowbit(x) (x&(-x))
#define MID(x,y) (x+((y-x)>>1))
#define eps 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LLINF 1LL<<62

template<class T>
inline bool read(T &n)
{
    T x = 0, tmp = 1; char c = getchar();
    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
    if(c == EOF) return false;
    if(c == '-') c = getchar(), tmp = -1;
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
    n = x*tmp;
    return true;
}
template <class T>
inline void write(T n)
{
    if(n < 0)
    {
        putchar('-');
        n = -n;
    }
    int len = 0,data[20];
    while(n)
    {
        data[len++] = n%10;
        n /= 10;
    }
    if(!len) data[len++] = 0;
    while(len--) putchar(data[len]+48);
}
//-----------------------------------


int n;  
char s[147][147];  
int G[147][147];
int in[147];//入度  
char ans[147];  

void toposort()//拓扑排序  
{  
    queue<int> q;  
    int  k=0;  
    for(int i=0; i<26; i++)  
        if(!in[i])  
        {  
            q.push(i);  
            ans[k++]='a'+i;  
        }  
  
    while(!q.empty())  
    {  
        int f = q.front();q.pop();  
        for(int i=0; i<26; i++)  
        {  
            if(G[f][i])
            {  
                in[i]--;  
                if(!in[i])  
                {  
                    q.push(i);  
                    ans[k++]='a'+i;  
                }  
            }  
        }  
    }  
    if(k<26)  
    {  
        puts("Impossible");  
    }  
    else  
    {  
        ans[k] = '\0';  
        puts(ans);  
    }  
}  
int main()  
{  
    while(read(n))  
    {  
        CLR(in,0);  
        CLR(G,0);  
        for(int i=0; i<n; i++)  
            scanf("%s",s[i]);  
        int mark = 1;  
        for(int i=0; i<n-1 && mark; i++)  
        {  
            int len1=strlen(s[i]);  
            int len2=strlen(s[i+1]);  
            int flag=0;  
            for(int j=0; j<len1 && j<len2; j++)  
            {  
                if(s[i][j]!=s[i+1][j])  
                {  
                    if(!G[s[i][j]-'a'][s[i+1][j]-'a'])  
                    {  
                        G[s[i][j]-'a'][s[i+1][j]-'a']=1;  
                        in[s[i+1][j]-'a']++;  
                    }  
                    flag=1;  
                    break;  
                }  
            }  
            if(!flag && len1>len2)//特判,前缀相同,且前一字符串币后一字符串还长,肯定不合法,这里wa了一次 
                mark=0;  
        }  
        if(!mark)  
        {  
            printf("Impossible\n");  
            return 0;  
        }  
        toposort();  
    }  
    return 0;  
}  



题意:

给你一些卡片,他们能够跳跃距离为L[i],花费为C[i]

求能够访问所有的点的最小花费是多少

解题思路:

就是通过将几个L[i]加加减减然后能够凑出 1 就能够访问所有的点

由裴蜀定理a*x + b*y = gcd(x,y) 可以得知,当x,y的最大公约数为1的时候,总存在a,b使得x,y凑出来为1,则满足题意

//      whn6325689
//		Mr.Phoebe
//		http://blog.csdn.net/u013007900
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#include <functional>
#include <numeric>
#pragma comment(linker, "/STACK:1024000000,1024000000")


using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef vector<int> vi;

#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lowbit(x) (x&(-x))
#define MID(x,y) (x+((y-x)>>1))
#define eps 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define IINF 1<<30
#define LLINF 1LL<<62

template<class T>
inline bool read(T &n)
{
    T x = 0, tmp = 1; char c = getchar();
    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
    if(c == EOF) return false;
    if(c == '-') c = getchar(), tmp = -1;
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
    n = x*tmp;
    return true;
}
template <class T>
inline void write(T n)
{
    if(n < 0)
    {
        putchar('-');
        n = -n;
    }
    int len = 0,data[20];
    while(n)
    {
        data[len++] = n%10;
        n /= 10;
    }
    if(!len) data[len++] = 0;
    while(len--) putchar(data[len]+48);
}
//-----------------------------------

int n, l[305], c[305];

map<int,int> dp[305];

int solve(int id=0, int gcd=0)
{
    if(id>=n)
		return gcd==1?0:IINF;
    if(dp[id].count(gcd))
        return dp[id][gcd];
    return
		dp[id][gcd]=min(solve(id+1, __gcd(gcd, l[id]))+c[id],solve(id+1, gcd));
}

int main()
{
    
    read(n);   
    for(int i=0; i<n; i++)
        read(l[i]);
    for(int i=0; i<n; i++)
        read(c[i]);
    int ans=solve();
    if(ans >= IINF)
		write(-1);
    else
		write(ans);
    putchar('\n');
    return 0;
}

你可能感兴趣的:(Codeforces Round #290 (Div. 2) C. Fox And Names && D. Fox And Jumping)