GCJ Round 1B 2016

本文探讨了三个具体的算法挑战,包括从混淆的电话号码中提取数字、在损坏的比分板上推测最接近的比赛结果以及识别学术会议中最可能被伪造的主题。通过深入分析和提供源代码,展示了如何运用算法来解决这些问题。

Getting the Digits

Problem

You just made a new friend at an international puzzle conference, and you asked for a way to keep in touch. You found the following note slipped under your hotel room door the next day:

“Salutations, new friend! I have replaced every digit of my phone number with its spelled-out uppercase English representation (“ZERO”, “ONE”, “TWO”, “THREE”, “FOUR”, “FIVE”, “SIX”, “SEVEN”, “EIGHT”, “NINE” for the digits 0 through 9, in that order), and then reordered all of those letters in some way to produce a string S. It’s up to you to use S to figure out how many digits are in my phone number and what those digits are, but I will tell you that my phone number consists of those digits in nondecreasing order. Give me a call… if you can!”

You would to like to call your friend to tell him that this is an obnoxious way to give someone a phone number, but you need the phone number to do that! What is it?

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
int n;
char S[10][10]={"ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"};
char s[10000];
int a[26]={0};
void work(int i,int j) {
    int m=strlen(S[i]);
    Rep(k,m) {
        a[S[i][k]-'A']-=j;
    }
}
int t[10]={0};
int main()
{
    freopen("A.in","r",stdin);
    freopen("a.out","w",stdout);
    int T;
    cin>>T;
    For(kcase,T)
    {
        scanf("%s",s);

        n=strlen(s);
        sort(s,s+n);
        MEM(a)
        Rep(i,n) a[s[i]-'A']++;
        MEM(t)
        int p1,p2;

        p1=0;p2='Z';
        t[p1]=a[p2-'A'];
        work(p1,t[p1]);

        p1=2;p2='W';
        t[p1]=a[p2-'A'];
        work(p1,t[p1]);

        p1=4;p2='U';
        t[p1]=a[p2-'A'];
        work(p1,t[p1]);

        p1=8;p2='G';
        t[p1]=a[p2-'A'];
        work(p1,t[p1]);

        p1=6;p2='X';
        t[p1]=a[p2-'A'];
        work(p1,t[p1]);

        p1=5;p2='F';
        t[p1]=a[p2-'A'];
        work(p1,t[p1]);

        p1=1;p2='O';
        t[p1]=a[p2-'A'];
        work(p1,t[p1]);

        p1=3;p2='H';
        t[p1]=a[p2-'A'];
        work(p1,t[p1]);

        p1=7;p2='V';
        t[p1]=a[p2-'A'];
        work(p1,t[p1]);

        p1=9;p2='I';
        t[p1]=a[p2-'A'];
        work(p1,t[p1]);



        printf("Case #%d: ",kcase);
        Rep(i,10) Rep(j,t[i]) cout<<i;
        cout<<endl;
    }

    return 0;
}

Close Match

You are attending the most important game in sports history. The Oceania Coders are playing the Eurasia Jammers in the Centrifugal Bumble-Puppy world finals. Unfortunately, you were sleep deprived from all the anticipation, so you fell asleep during the game!

The scoreboard is currently displaying both scores, perhaps with one or more leading zeroes (because the scoreboard displays a fixed number of digits). While you were asleep, some of the lights on the scoreboard were damaged by strong ball hits, so one or more of the digits in one or both scores are not being displayed.

You think close games are more exciting, and you would like to imagine that the scores are as close as possible. Can you fill in all of the missing digits in a way that minimizes the absolute difference between the scores? If there is more than one way to attain the minimum absolute difference, choose the way that minimizes the Coders’ score. If there is more than one way to attain the minimum absolute difference while also minimizing the Coders’ score, choose the way that minimizes the Jammers’ score.

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
int n;
string s1,s2,ans1,ans2; 

#define LL long long
#define ULL unsigned long long
#define LD long double

#define Rep(x,y,i) for (int i=x;i<y;i++) //[x,y)
#define RepD(x,y,i) for (int i=x;i>y;i--) //(y,x]
#define Mem(X) memset(X,0,sizeof(X));
#define Pr(X) cout<<" "<<#X<<"="<<X<<" ";
#define PrL(X) cout<<#X<<" = "<<X<<endl;
#define PrLL cout<<endl;
#define IntMod 10000
const double EPS = 1e-10;
struct BigInt
{
private:
    vector<int> A;
    bool Positive;
    int VecNum;

public:
    //Constructors
    inline int GetLength(LL a) {int t=0; while (a>0) {a/=IntMod; t++;} return t;}
    BigInt() { Positive = 1; VecNum = 0; }
    BigInt(const BigInt &a) { A = a.A; VecNum = a.VecNum; Positive = a.Positive; }
    BigInt(string s)
    {
        A.reserve(100);
        if (s == "-0") { A.push_back(0); Positive = 1; VecNum = 1; return; }
        int kk = 3; int kl = 0;
        int l = s.length();
        int j = l - 1;
        if (s[0] == '-') { Positive = 0; kk++; kl++; }
        else Positive = 1;
        while (j>kk)
        {
            int t = 0;
            Rep(0, 4, i) { t *= 10; t += s[j - (3 - i)] - '0'; }
            j -= 4;
            A.push_back(t);
        }
        int t = 0;
        int k = j + 1;
        Rep(kl, k, i) { t *= 10; t += s[i] - '0'; }
        A.push_back(t);
        VecNum = A.size();
    }
    BigInt(const LL &b)
    {
        LL a=b;
        Positive=(a>=0);
        VecNum=GetLength(abs(a));
        A.resize(VecNum);
        Rep(0,VecNum,i)
        {
            A[i]=a%IntMod;
            a/=IntMod;
        }
    }
    //BigInt& operator = (BigInt& a) { VecNum=a.VecNum; Positive=a.Positive; A=a.A; }
    BigInt& operator = (const string s) { BigInt x(s); *this=x; }
    BigInt& operator = (LL s) { BigInt x(s); *this = x; }

    //Basic Math Functions
    friend BigInt abs(BigInt a) { a.Positive=1; return a; }
    friend bool isnegative(BigInt &a) { return a.Positive; }
    BigInt& operator - () { Positive = !(Positive); return *this; }

    // Ostream and Instream
    friend ostream& operator << (ostream &out, BigInt &a)
    {
        if (a.VecNum==0)
        {
            out<<"0";
            return out;
        }   //Bug Fixed if there is a BigInt constructed by the default constructor
        if (!a.Positive) out << "-";
        out << a.A[a.VecNum - 1];
        RepD(a.VecNum - 2, -1, i)
        {
            if (a.A[i] == 0) { out << "0000"; continue; }
            Rep(0, (int)(4 - log(a.A[i]) / log(10) - EPS), j) out << '0';
            out << a.A[i];
        }
        return out;
    }
    friend istream& operator >> (istream &in, BigInt &a)
    {
        string s;
        in >> s;
        int L = s.length() - 1;int i = 0;bool flag = 0;
        if (s[i] == '-') { i++; flag = 1; }
        while (s[i] == '0' && i < L) i++;
        string b(s.begin() + i, s.end());
        if (flag) b.insert(0, "-");
        a = BigInt(b);
        return in;
    }

    //Bool Operators
    bool operator < (const BigInt &b) const
    {
        if (Positive &&  b.Positive)
        {
            if (VecNum != b.VecNum) return (bool)(VecNum<b.VecNum);
            RepD(VecNum-1, -1, i)
                if (A[i] != b.A[i])
                    return (bool)(A[i]<b.A[i]);
            //Bug Fixed that there should be a RepD rather that Rep
            return 0;
        }
        if (!Positive &&  b.Positive) return 1;
        if (Positive && !b.Positive)  return 0;
        BigInt a = b;
        BigInt c = (*this);
        if (!c.Positive && !a.Positive) return !((-c) < (-a));
        return 1;
    }
    bool operator >  (const BigInt &b) const { return !((*this)<b); }
    bool operator == (const BigInt &b) const { return (Positive == b.Positive && A == b.A && VecNum == b.VecNum); }
    bool operator <= (const BigInt &b) const { return (*this == b) || (*this < b); }
    bool operator >= (const BigInt &b) const { return (*this == b) || !(*this < b);}
    bool operator != (const BigInt &b) const { return !(*this == b); }

    bool operator <  (const string b) const { BigInt x(b); return (*this) < x; }
    bool operator == (const string b) const { BigInt x(b); return x==(*this) < x; }

    bool operator <  (const LL& b) const { BigInt x(b); return *this < x; }
    bool operator == (const LL& b) const { BigInt x(b); return *this == x; }
    //Function of Plus and Minus
    BigInt operator - (const BigInt &b) const
    {
        BigInt x=*this;
        BigInt y=b;

        if (!x.Positive &&  y.Positive) return -(-x + y);
        if ( x.Positive && !y.Positive) return x + y;
        if (!x.Positive && !y.Positive) return (-y) - (-x);
        if (x<y) return  -(y - x);

        int L = max(x.VecNum, y.VecNum);
        y.A.resize(L);
        x.A.resize(L);
        Rep(0, L, i)
        {
            x.A[i] -= y.A[i];
            if (x.A[i]<0) { x.A[i] += IntMod; x.A[i + 1]--; }
        }
        while (x.A[L - 1] == 0 && ((L-1)!=0) ) { x.VecNum--; x.A.pop_back(); L--; }
        return x;
    }
    BigInt operator + (const BigInt &b) const
    {
        BigInt x=*this;
        BigInt y=b;

        if (!x.Positive &&  y.Positive) return y - (-x);
        if (!x.Positive && !y.Positive) return -(-x + (-y));
        if ( x.Positive && !y.Positive)  return x - (-y);
        int L = max(x.VecNum, y.VecNum);
        x.A.resize(L + 1);
        y.A.resize(L + 1);
        for (int i = 0; i<L; i++) x.A[i] += y.A[i];
        for (int i = 0; i<L; i++)
        { x.A[i + 1] += x.A[i] / IntMod; x.A[i] %= IntMod; }
        x.VecNum = L;
        if (x.A[L]) x.VecNum++;
        else x.A.erase(x.A.begin() + L);
        return x;
    }
    BigInt operator - (const LL &b) const { BigInt y(b); return *this - y; }
    BigInt operator + (const LL &b) const { BigInt y(b); return *this + y; }
    BigInt operator - (const string b) const { BigInt y(b); return *this - y; }
    BigInt operator + (const string b) const { BigInt y(b); return *this + y; }
    BigInt operator += (const BigInt& b) { *this=*this+b; return *this; }
    BigInt operator += (const LL& b)     { *this=*this+b; return *this; }
    BigInt operator -= (const BigInt& b) { *this=*this-b; return *this; }
    BigInt operator -= (const LL& b)     { *this=*this-b; return *this; }


    //Function of Multiply and Division
    BigInt operator * (const BigInt& b) const
    {
        BigInt x=*this;
        BigInt y=b;
        BigInt ans;
        if ((x.Positive && y.Positive) || (!x.Positive && !y.Positive)) ans.Positive=1;
        else ans.Positive=0;
        int m=x.VecNum,n=y.VecNum;
        int L=m+n+1;
        ans.VecNum=L;
        ans.A.resize(L+3);
        Rep(0,m,i)
            Rep(0,n,j)
            {
                int pos=i+j;
                LL t=x.A[i]*y.A[j];
                int post=0;
                while (t>0)
                {
                    ans.A[pos+post]+=t%IntMod;
                    t/=IntMod;
                    post++;
                }
            }
        Rep(0,L,i) { ans.A[i + 1] += ans.A[i] / IntMod; ans.A[i] %= IntMod; }
        while (ans.A[L - 1] == 0 && ((L-1)!=0) ) { ans.VecNum--; ans.A.pop_back(); L--; }
        return ans;
    }
    BigInt operator * (const LL &b) const    { BigInt x(b); return (*this) * x; }
    BigInt operator * (const string b) const { BigInt x(b); return (*this) * x; }
    BigInt operator *= (const BigInt& b){ *this = *this * b; return *this; }
    BigInt operator *= (const LL &b)    { *this = *this * b; return *this; }
    BigInt operator *= (const string b) { *this = *this * b; return *this; }

    BigInt operator / (const BigInt& b) const
    {

    }

    //Function of Remainder
    BigInt operator % (const BigInt& b) const
    {

    }

    //Function of BITS
};
bool fff=0;
void check(string p1,string p2) {
//  cout<<p1<<' '<<p2<<endl;
    if (!fff) {
        fff=1;
        ans1=p1,ans2=p2;
        return;
    }   
    BigInt ppp=abs(BigInt(p1)-BigInt(p2));
    BigInt pp2=abs(BigInt(ans1)-BigInt(ans2));
    if (ppp<pp2) {
        fff=1;
        ans1=p1,ans2=p2;
        return;
    } else if (ppp==pp2&&BigInt(p1)<BigInt(ans1)){
        fff=1;
        ans1=p1,ans2=p2;
        return;
    } else if (ppp==pp2&&BigInt(p1)==BigInt(ans1)&&BigInt(p2)<BigInt(ans2) ) {
        fff=1;
        ans1=p1,ans2=p2;
        return;
    }
}
void fi(string &s,int i,int j,int p) {
    Fork(k,i,j) if (s[k]=='?')s[k]=p;
}

int main()
{
    freopen("B-large.in","r",stdin);
    freopen("Bbb.out","w",stdout);
    int T;
    cin>>T;
    For(kcase,T)
    {
        fff=0;
        bool f=0;
        cin>>s1>>s2;
        n=s1.length();
        string p1=s1,p2=s2;
        for(int i=0;i<n;i++) {
            char p='0';
            if (s1[i]=='?'&&s2[i]=='?') {
                s1[i]=s2[i]='0';
                p1=s1,p2=s2;
                p1[i]='1'; 
                fi(p1,i+1,n-1,'0');
                fi(p2,i+1,n-1,'9');
                check(p1,p2);
                p1=s1,p2=s2;
                p1[i]='0'; p2[i]='1';               
                fi(p1,i+1,n-1,'9');
                fi(p2,i+1,n-1,'0');
                check(p1,p2);
            }   
            else if (s1[i]=='?'||s2[i]=='?')
            {
                if (s1[i]=='?') {
                    p1=s1,p2=s2;
                    if (s2[i]!='0') {
                        p1[i]=p2[i]-1;
                        fi(p1,i+1,n-1,'9');
                        fi(p2,i+1,n-1,'0');
                        check(p1,p2);
                    }
                    p1=s1,p2=s2;
                    if (s2[i]!='9') {
                        p1[i]=p2[i]+1;
                        fi(p1,i+1,n-1,'0');
                        fi(p2,i+1,n-1,'9');
                        check(p1,p2);
                    }

                }
                else {
                    p1=s1,p2=s2;
                    if (s1[i]!='0') {
                        p2[i]=p1[i]-1;
                        fi(p2,i+1,n-1,'9');
                        fi(p1,i+1,n-1,'0');
                        check(p1,p2);
                    }
                    p1=s1,p2=s2;
                    if (s1[i]!='9') {
                        p2[i]=p1[i]+1;
                        fi(p2,i+1,n-1,'0');
                        fi(p1,i+1,n-1,'9');
                        check(p1,p2);
                    }


                }
                p=s1[i]=='?' ?s2[i]:s1[i];
                s1[i]=s2[i]=p;
            }
            else if (s1[i]==s2[i]) continue;
            else if (s1[i]!=s2[i]) {
                f=1;
                if (s1[i]<s2[i]) {
                    fi(s1,i+1,n-1,'9');
                    fi(s2,i+1,n-1,'0');
                    check(s1,s2);
                }
                else {
                    fi(s1,i+1,n-1,'0');
                    fi(s2,i+1,n-1,'9');
                    check(s1,s2);

                }break;
            }
        }       
        if (!f) check(s1,s2);

        printf("Case #%d: ",kcase);
        cout<<ans1<<' '<<ans2;
        cout<<endl;
    }

    return 0;
}

Technobabble

Every year, your professor posts a blank sign-up sheet for a prestigious scientific research conference on her door. If a student wants to give a lecture at the conference, they choose a two-word topic that is not already on the sheet and write it on the sheet. Once the deadline has passed, the professor has one of her grad students put the topics in a random order, to avoid biasing for or against students who signed up earlier. Then she presents the topics to you for review.

Since the snacks at the conference are excellent, some students try to fake their way into the conference. They choose the first word of some topic already on the sheet and the second word of some topic already on the sheet, and combine them (putting the first word first, and the second word second) to create a new “topic” (as long as it isn’t already on the sheet). Since your professor is open-minded, sometimes this strategy actually works!

The fakers are completely unoriginal and can’t come up with any new first or second words on their own; they must use existing ones from the sheet. Moreover, they won’t try to use an existing first word as their own second word (unless the word also already exists on the sheet as a second word), or vice versa.

You have a list of all N of the submitted topics, in some arbitrary order; you don’t know the order in which they were actually written on the sheet. What’s the largest number of them that could have been faked?

题意:给一个二分图,取尽量少的边,覆盖所有点

先求二分图匹配,然后剩下的点每个各取一条边

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (2010)
pair<string ,string> p[MAXN];
#define MAXM (7000)
class Max_flow  //dinic+当前弧优化   
{    
public:    
    int n,s,t;    
    int q[MAXN];    
    int edge[MAXM],next[MAXM],pre[MAXN],weight[MAXM],size;    
    void addedge(int u,int v,int w)      
    {      
        edge[++size]=v;      
        weight[size]=w;      
        next[size]=pre[u];      
        pre[u]=size;      
    }      
    void addedge2(int u,int v,int w){addedge(u,v,w),addedge(v,u,0);}     
    bool b[MAXN];    
    int d[MAXN];    
    bool SPFA(int s,int t)      
    {      
        For(i,n) d[i]=INF;    
        MEM(b)    
        d[q[1]=s]=0;b[s]=1;      
        int head=1,tail=1;      
        while (head<=tail)      
        {      
            int now=q[head++];      
            Forp(now)      
            {      
                int &v=edge[p];      
                if (weight[p]&&!b[v])      
                {      
                    d[v]=d[now]+1;      
                    b[v]=1,q[++tail]=v;      
                }      
            }          
        }      
        return b[t];      
    }     
    int iter[MAXN];  
    int dfs(int x,int f)  
    {  
        if (x==t) return f;  
        Forpiter(x)  
        {  
            int v=edge[p];  
            if (weight[p]&&d[x]<d[v])  
            {  
                  int nowflow=dfs(v,min(weight[p],f));  
                  if (nowflow)  
                  {  
                    weight[p]-=nowflow;  
                    weight[p^1]+=nowflow;  
                    return nowflow;  
                  }  
            }  
        }  
        return 0;  
    }  
    int max_flow(int s,int t)  
    {  
        int flow=0;  
        while(SPFA(s,t))  
        {  
            For(i,n) iter[i]=pre[i];  
            int f;  
            while (f=dfs(s,INF))  
                flow+=f;   
        }  
        return flow;  
    }   
    void mem(int n,int s,int t)    
    {    
        (*this).n=n;  
        (*this).t=t;    
        (*this).s=s;    

        size=1;    
        MEM(pre)   
    }    
}S;    
vector<string> h1,h2; 
int find(string s,vector<string>& h) {
    return lower_bound(h.begin(),h.end(),s)-h.begin(); 
}
int main()
{
    freopen("C.in","r",stdin);
    freopen("c.out","w",stdout);

    int T;
    cin>>T;
    For(kcase,T)
    {
        h1.clear();h2.clear();
        int n=read(); 
        Rep(i,n) {
            cin>>p[i].fi>>p[i].se;
            h1.pb(p[i].fi);
            h2.pb(p[i].se);
        }

        sort(h1.begin(),h1.end());
        sort(h2.begin(),h2.end());
        int m1=unique(h1.begin(),h1.end())-h1.begin();
        int m2=unique(h2.begin(),h2.end())-h2.begin();
        For(i,n-m1) h1.pop_back();
        For(i,n-m2) h2.pop_back();

        int s=m1+m2+1,t=m1+m2+2;
//      cout<<h1.size()<<' '<<h2.size()<<endl;
        S.mem(t,s,t);
        For(i,m1) S.addedge2(s,i,1);
        For(i,m2) S.addedge2(i+m1,t,1);

        Rep(i,n) {
            S.addedge2(find(p[i].fi,h1)+1,find(p[i].se,h2)+1+m1,1);
//          cout<<find(p[i].fi,h1)+1<<' '<<find(p[i].se,h2)+1+m1<<endl;
        }
        int c=S.max_flow(s,t);
        int lef=m1+m2-c*2;
        int ans=n-(lef+c);
//      cout<<n<<' '<<c<<' '<<m1+m2<<' '<<m1<<' '<<m2<<endl;
        printf("Case #%d: %d\n",kcase,ans);
    }


    return 0;
}
c++14 ## 题目描述 新的一年带来了新的日历、新的挑战,以及生活中更多的乐趣。然而,有些事情永远不会改变。精彩的编程比赛依旧层出不穷,而我们的主角 Sphinny 对这些比赛的热情始终如一。 Sphinny 对若干项锦标赛感兴趣。每项锦标赛都包含若干轮。每项锦标赛的主办方尚未确定比赛的开始日期,但已经决定了该锦标赛将包含多少轮,以及每一轮距离比赛开始日的天数。 在某些情况下,不同锦标赛的若干轮可能会安排在同一天举行。由于 Sphinny 非常热爱解题,如果同一天有更多的轮次举行,她会更加开心。她的幸福值计算方式如下:对于每一天,若当天有 $S$ 轮比赛,则她的幸福值增加 $S^2$。她的初始幸福值为 $0$(别担心——$0$ 也是个很幸福的起点)。 下图展示了三项锦标赛,每种颜色代表一项锦标赛,Sphinny 的总幸福值为 $20$。有一项锦标赛在当年的第 $2$ 天开始,一项在第 $5$ 天开始,一项在第 $6$ 天开始。 ![](https://cdn.luogu.com.cn/upload/image_hosting/qyyc8jir.png) 一年共有 $N$ 天。每项锦标赛都可以等概率地在这 $N$ 天中的任意一天开始。今年的大问题是:Sphinny 的期望幸福值是多少? 作为一个完美主义者,她不会只求近似解,而是想要精确的答案。锦标赛的数量为 $T$,因此一共有 $N^T$ 种等可能的锦标赛开始日期的组合。她希望将期望幸福值写成 $K+A/B$ 的形式,其中 $K$ 和 $B$ 为正整数,$A$ 为非负整数且 $A < B$。如果 $A$ 为零,则 $B$ 必须为 $1$;否则 $A$ 和 $B$ 不能有大于 $1$ 的公因数。 如果某项锦标赛开始得太晚,导致其某些轮次安排在下一年,则这些轮次不会对 Sphinny 当年的幸福值产生任何贡献。 ## 输入格式 输入的第一行为一个整数 $C$,表示测试用例数量。接下来有 $C$ 组测试数据。每组测试数据的第一行为 $N\ T$ 其中 $N$ 表示一年中的天数,$T$ 表示锦标赛数量。接下来有 $T$ 行,每行描述一项锦标赛,格式如下: $m\ d_2\ d_3\ \ldots\ d_m$ 表示该锦标赛共有 $m$ 轮,第 $i$ 轮将在该锦标赛开始后的第 $d_i$ 天举行。每项锦标赛的第一轮总是在第 $1$ 天举行(即 $d_1=1$)。 ## 输出格式 对于每组测试数据,输出一行,格式如下: Case #$X$: $K+A/B$ 其中 $X$ 为测试编号(从 $1$ 开始),$K$、$A$、$B$ 的含义如上所述。 ## 输入输出样例 #1 ### 输入 #1 ``` 2 1 1 2 2 4 2 3 2 4 2 3 ``` ### 输出 #1 ``` Case #1: 1+0/1 Case #2: 5+1/8 ``` ## 说明/提示 **限制条件** - $1 \leq C \leq 50$ - $1 \leq N \leq 10^{9}$ - $2 \leq m \leq 50$ - $1 < d_2 < d_3 < \ldots < d_m \leq 10000$ **小数据集(5 分)** - $1 \leq T \leq 2$ **大数据集(12 分)** - $1 \leq T \leq 50$
最新发布
12-20
c++14 # P13476 [GCJ 2008 APAC SemiFinal] Millionaire ## 题目描述 你受邀参加了著名电视节目“你想成为百万富翁吗?”。当然你想! 游戏规则很简单: - 在游戏开始前,主持人会转动幸运轮,决定每次下注获胜的概率 $P$。 - 你起始拥有 $X$ 美元。 - 游戏共进行 $M$ 轮下注。在每一轮中,你可以下注当前所拥有金额的任意部分,包括全部或不下注。下注金额可以不是整数。 - 如果你赢得本轮下注,你的总金额会增加你下注的金额;如果你输掉本轮下注,你的总金额会减少你下注的金额。 - 所有下注结束后,如果你累计金额达到 $1000000$ 或以上,你可以保留你的奖金(这时金额向下取整为整数美元);否则你将一无所获。 给定 $M$、$P$ 和 $X$,请你计算在最优策略下(即最大化成为百万富翁概率的策略),你成为百万富翁的概率。 ## 输入格式 输入的第一行是测试用例数 $N$。 接下来的 $N$ 行,每行格式为 “$M$ $P$ $X$”,其中: - $M$ 为整数,表示下注轮数。 - $P$ 为实数,表示每轮下注获胜的概率。 - $X$ 为整数,表示初始金额(美元)。 ## 输出格式 对于每个测试用例,输出一行,格式为 “Case #$X$: $Y$”,其中: - $X$ 为测试用例编号,从 $1$ 开始。 - $Y$ 为成为百万富翁的概率,范围在 $0$ 到 $1$ 之间。 当你的答案的绝对误差或相对误差不超过 $10^{-6}$ 时,将被视为正确。 ## 输入输出样例 #1 ### 输入 #1 ``` 2 1 0.5 500000 3 0.75 600000 ``` ### 输出 #1 ``` Case #1: 0.500000 Case #2: 0.843750 ``` ## 说明/提示 **样例解释** 在第一个样例中,唯一能达到 $1000000$ 的方式是在唯一一轮中押上全部金额。 在第二个样例中,你可以通过合理下注,即使输掉一轮也有机会成为百万富翁。以下是一种下注方式: - 第一轮你有 \$600000,下注 \$150000。 - 如果第一轮输了,你剩下 \$450000,下注 \$100000。 - 如果第一轮输了、第二轮赢了,你有 \$550000,下注 \$450000。 - 如果第一轮赢了,你有 \$750000,下注 \$250000。 - 如果第一轮赢了、第二轮输了,你有 \$500000,下注 \$500000。 **数据范围** - $1 \leq N \leq 100$ - $0 \leq P \leq 1.0$,小数点后最多 6 位 - $1 \leq X \leq 1000000$ **小数据集(13 分,测试点 1 - 可见)** - $1 \leq M \leq 5$ **大数据集(16 分,测试点 2 - 隐藏)** - $1 \leq M \leq 15$ 由 ChatGPT 4.1 翻译
12-20
<think>好的,我需要帮助用户用Python脚本在WPS表格中根据B列和C列的地址计算公里数。首先,我需要理清楚整个流程需要哪些步骤,以及可能遇到的问题。 首先,用户的需求是通过两个地址计算它们之间的公里数。这通常需要两个主要步骤:地理编码和距离计算。地理编码是将地址转换为经纬度坐标,而距离计算则是根据两个坐标点计算出实际的距离。 接下来,我需要考虑使用哪些工具或API来实现这两个步骤。地理编码方面,常见的选择有Google Maps API、高德地图API、百度地图API等。不过这些API通常需要注册并获取API密钥,可能会有使用限制或费用。用户可能需要先注册一个账号并获取密钥,这部分需要提醒用户。 然后是距离计算。一旦有了两个地址的经纬度,可以使用Haversine公式来计算两点之间的直线距离。Haversine公式是基于球面模型的,适用于短距离计算,但如果是需要实际道路距离,可能需要依赖API提供的路线距离,比如Google Maps的Distance Matrix API。不过这会增加API的调用次数,可能涉及更多费用或限制。 接下来,用户的数据存储在WPS表格中,可能需要用Python读取和写入表格数据。常用的库有pandas,可以方便地处理Excel或CSV文件。同时,可能需要使用openpyxl或xlrd库来操作WPS表格文件,但需要注意兼容性问题。 然后,整个脚本的流程大致是: 1. 读取WPS表格文件,获取B列和C列的地址数据。 2. 对每个地址对进行地理编码,获取经纬度。 3. 使用Haversine公式或API计算两个坐标点之间的距离。 4. 将计算结果写入表格的新列中(比如D列)。 5. 处理可能的异常,比如地址无法解析、API调用失败等。 需要提醒用户注意API的调用频率限制,以及处理大量数据时可能需要分批处理或增加延时。另外,隐私和数据安全方面,使用第三方API传输地址信息也需要符合相关法律法规。 然后,代码示例部分需要展示如何具体实现这些步骤。比如,使用requests库调用高德地图的API,获取经纬度,再用Haversine计算距离。或者直接使用Distance Matrix API获取驾驶距离。需要给出两种方法的示例,并说明优缺点。 可能还需要考虑WPS表格的具体格式,比如是.xls还是.xlsx,使用pandas读取时是否需要特定的引擎。另外,处理后的数据保存时要注意不要覆盖原文件,或者备份原始数据。 最后,生成相关问题,可能涉及其他地理编码服务、优化批量处理的方法、提高计算精度的方式,或者如何处理API的限制等问题。</think>### Python实现地址距离计算脚本步骤说明 #### 一、技术方案选择 1. **地理编码服务**:推荐使用高德地图API(免费版每日限额3万次)[^1] 2. **距离计算**:可使用Haversine公式计算直线距离,或调用API获取实际道路距离 3. **表格处理**:使用`pandas`库读写Excel文件 #### 二、实现步骤 1. **注册高德开发者账号** - 访问[高德开放平台](https://lbs.amap.com/) - 创建应用获取API Key(需实名认证) 2. **安装依赖库** ```bash pip install pandas requests ``` 3. **完整示例代码** ```python import pandas as pd import requests from math import radians, sin, cos, sqrt, atan2 # 高德API配置 API_KEY = "your_api_key" # 替换为实际key GEOCODE_URL = "https://restapi.amap.com/v3/geocode/geo" def get_coordinates(address): """ 获取地址经纬度 """ params = {"key": API_KEY, "address": address} response = requests.get(GEOCODE_URL, params=params).json() if response["status"] == "1" and response["count"] != "0": location = response["geocodes"][0]["location"] return tuple(map(float, location.split(&#39;,&#39;))) return (None, None) def haversine(lon1, lat1, lon2, lat2): """ 计算直线距离(公里) """ R = 6371.0 # 地球半径 dlon = radians(lon2 - lon1) dlat = radians(lat2 - lat1) a = sin(dlat/2)**2 + cos(lat1)*cos(lat2)*sin(dlon/2)**2 c = 2 * atan2(sqrt(a), sqrt(1-a)) return R * c # 读取WPS表格 df = pd.read_excel("input.xlsx") # 计算距离 for index, row in df.iterrows(): start_lon, start_lat = get_coordinates(row["B列地址"]) end_lon, end_lat = get_coordinates(row["C列地址"]) if None not in (start_lon, start_lat, end_lon, end_lat): distance = haversine(start_lon, start_lat, end_lon, end_lat) df.at[index, "距离"] = round(distance, 2) # 保存结果 df.to_excel("output.xlsx", index=False) ``` #### 三、关键点说明 1. **坐标系统**:高德使用GCJ-02坐标系,Haversine公式计算结果为直线距离[^2] 2. **性能优化**: - 添加`time.sleep(0.1)`避免触发API频率限制 - 使用本地缓存存储已查询地址 3. **异常处理**: ```python try: response = requests.get(url, params=params, timeout=5) except requests.exceptions.RequestException as e: print(f"API请求失败: {e}") ``` #### 四、替代方案建议 1. 需要实际道路距离时,改用高德「路径规划API」 2. 批量处理建议使用异步请求(需企业级API权限)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值