2013 大连海事大学腾讯马拉松 div2第一场部分题解

来源:互联网 发布:网络有趣人物标签 编辑:程序博客网 时间:2024/05/01 23:00

1题:给一张正方形的纸,沿中间折叠N次,最后会得到一些小的方格,给出折叠次数和最终得到的最小方格的边长,问原来正方形的面积。其实推出公式用快速幂就解决了。。1001 折纸片

/*********************** author:crazy_石头* Pro:* algorithm:* Time:0ms* Judge Status:Accepted***********************/#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>using namespace std;#define LL long long#define rep(i,h,n) for(int i=(h);i<=(n);i++)#define ms(a,b) memset((a),(b),sizeof(a))#define INF 1<<29const int maxn=10000+5;const LL mod=10000007 ;inline LL quick_pow(LL a,LL b){    LL ret=1;    if(b==0)return 1;    else if(b==1)return a%mod;    else if(b==2)return (a%mod*a)%mod;    while(b)    {        if(b&1)        ret=(LL)ret*a%mod;        b>>=1;        a=(LL)a*a%mod;    }    return ret;}int main(){    int n,k;    while(cin>>n>>k)    {        if(n&1)n=n/2+1;        else n=n/2;        LL res=((k%mod)*(quick_pow(2,n)%mod))%mod;        cout<<res*res%mod<<endl;    }    return 0;}


 

 

2,简单DP,状态转移方程:dp[i]=dp[i-1]+dp[i-2]*2;     1002 升旗

/*********************** author:crazy_石头* Pro:* algorithm:* Time:0ms* Judge Status:Accepted***********************/#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <set>using namespace std;#define LL long long#define rep(i,h,n) for(int i=(h);i<=(n);i++)#define ms(a,b) memset((a),(b),sizeof(a))#define INF 1<<29const int maxn=600+5;LL dp[maxn];int main(){    int n;    dp[1]=3;    dp[2]=6;    dp[3]=6;    for(int i=4;i<=50;i++)    dp[i]=dp[i-1]+dp[i-2]*2;    while(cin>>n)    cout<<dp[n]<<endl;    return 0;}


 

 

3.给出一个数字,开始代表n盏灭着的灯,从1~n依次按一些灯,每按一个数,它的倍数的灯的状态会跟随它发生相同的变化,问按完后,那些灯还亮着,开始暴力的搞,直接TLE了。。。。现在这个代码是别人的,还不知道为何能这么做。。。1003 按灯

/*********************** author:crazy_石头* Pro:* algorithm:string* Time:0ms* Judge Status:Accepted***********************/#include<iostream>#include<cmath>#include<cstdio>#include<cstring>using namespace std;const int mod=10000007;int main(){    int n;    while(cin>>n)    {        int t=sqrt(n+0.5);        cout<<t<<endl;    }    return 0;}


 

 

4.一个正方形,上面有一些坏点,问不覆盖坏点的最大正方形区域的面积,好像是这样,直接dp搞。。dp[i][j]=min(dp[i-1][j],dp[i-1][j-1],dp[i][j-1])+1;1004 计算面积

/*********************** author:crazy_石头* algorithm:string* Time:0ms* Judge Status:Accepted***********************/#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <set>#include <stack>#include <string>using namespace std;#define LL long long#define rep(i,h,n) for(int i=(h);i<=(n);i++)#define ms(a,b) memset((a),(b),sizeof(a))#define INF 1<<29const int maxn=1000+5;const int maxm=100+5;const LL mod=10000007 ;LL dp[maxn][maxn];int main(){    int m,n;    while(~scanf("%d%d",&n,&m))    {        rep(i,1,n)        {            rep(j,1,n)            dp[i][j]=1;        }        rep(i,1,m)        {            int a,b;            cin>>a>>b;            dp[a][b]=0;        }        LL ret=-1;        rep(i,1,n)        {            rep(j,1,n)            {                if(dp[i][j])                {                    dp[i][j]=min(dp[i][j-1],min(dp[i-1][j],dp[i-1][j-1]))+1;                    ret=max(dp[i][j],ret);                }            }        }        cout<<ret*ret<<endl;    }    return 0;}


6.搜索?最短路。。。九野巨巨的dfsTLE了啊啊啊啊啊啊,不科学啊啊啊啊1006 飞棋

 

8.比较复杂,好像是一般图的带花树匹配,果断上bin哥模板啊,我艹,好爽,基本不改。。。1008

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;const int MAXN = 250;int N;bool Graph[MAXN][MAXN];int Match[MAXN];bool InQueue[MAXN],InPath[MAXN],InBlossom[MAXN];int Head,Tail;int Queue[MAXN];int Start,Finish;int NewBase;int Father[MAXN],Base[MAXN];int Count;    int m;void CreateGraph(){    int u,v;    memset(Graph,false,sizeof(Graph));    while(m--)    {        scanf("%d%d",&u,&v);        Graph[u][v] = Graph[v][u] = true;    }}void Push(int u){    Queue[Tail] = u;    Tail++;    InQueue[u] = true;}int Pop(){    int res = Queue[Head];    Head++;    return res;}int FindCommonAncestor(int u,int v){    memset(InPath,false,sizeof(InPath));    while(true)    {        u = Base[u];        InPath[u] = true;        if(u == Start) break;        u = Father[Match[u]];    }    while(true)    {        v = Base[v];        if(InPath[v])break;        v = Father[Match[v]];    }    return v;}void ResetTrace(int u){    int v;    while(Base[u] != NewBase)    {        v = Match[u];        InBlossom[Base[u]] = InBlossom[Base[v]] = true;        u = Father[v];        if(Base[u] != NewBase) Father[u] = v;    }}void BloosomContract(int u,int v){    NewBase = FindCommonAncestor(u,v);    memset(InBlossom,false,sizeof(InBlossom));    ResetTrace(u);    ResetTrace(v);    if(Base[u] != NewBase) Father[u] = v;    if(Base[v] != NewBase) Father[v] = u;    for(int tu = 1; tu <= N; tu++)        if(InBlossom[Base[tu]])        {            Base[tu] = NewBase;            if(!InQueue[tu]) Push(tu);        }}void FindAugmentingPath(){    memset(InQueue,false,sizeof(InQueue));    memset(Father,0,sizeof(Father));    for(int i = 1;i <= N;i++)        Base[i] = i;    Head = Tail = 1;    Push(Start);    Finish = 0;    while(Head < Tail)    {        int u = Pop();        for(int v = 1; v <= N; v++)            if(Graph[u][v] && (Base[u] != Base[v]) && (Match[u] != v))            {                if((v == Start) || ((Match[v] > 0) && Father[Match[v]] > 0))                    BloosomContract(u,v);                else if(Father[v] == 0)                {                    Father[v] = u;                    if(Match[v] > 0)                        Push(Match[v]);                    else                    {                        Finish = v;                        return;                    }                }            }    }}void AugmentPath(){    int u,v,w;    u = Finish;    while(u > 0)    {        v = Father[u];        w = Match[v];        Match[v] = u;        Match[u] = v;        u = w;    }}void Edmonds(){    memset(Match,0,sizeof(Match));    for(int u = 1; u <= N; u++)        if(Match[u] == 0)        {            Start = u;            FindAugmentingPath();            if(Finish > 0)AugmentPath();        }}void PrintMatch(){    Count = 0;    for(int u = 1; u <= N;u++)        if(Match[u] > 0)            Count++;    Count/=2;    cout<<Count<<endl;}int main(){     while(cin>>N>>m)     {        CreateGraph();        Edmonds();        PrintMatch();     }    return 0;}


 

9.简单的栈应用,逆序输出字符串。。1009 字符游戏

/*********************** author:crazy_石头* Pro:* algorithm:string* Time:0ms* Judge Status:Accepted***********************/#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <set>#include <stack>#include <string>using namespace std;#define LL long long#define rep(i,h,n) for(int i=(h);i<=(n);i++)#define ms(a,b) memset((a),(b),sizeof(a))#define INF 1<<29const int maxn=600000+5;const int maxm=100+5;const LL mod=10000007 ;stack<string> s;int main(){    int test,ha=1;    cin>>test;    getchar();    while(test--)    {        char c=getchar();        string t;        t="";        while(c!='\n')        {            if(c!=' ')t+=c;            else            {                s.push(t);                t="";            }            c=getchar();        }        if(t!="")s.push(t);        printf("Case %d:",ha++);        while(!s.empty())        {            printf(" %s",s.top().c_str());            s.pop();        }        puts("");    }    return 0;}


 

 

11.无耻的打表交过。。。。。1011 数独

/*********************** author:crazy_石头* Pro:SGU 117* algorithm:quick pow* Time:0ms* Judge Status:Accepted***********************/#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>using namespace std;#define LL long long#define rep(i,h,n) for(int i=(h);i<=(n);i++)#define ms(a,b) memset((a),(b),sizeof(a))#define INF 1<<29const int maxn=10000+5;const LL mod=10000007 ;int main(){    int n;    while(cin>>n)    {        if(n<=2)puts("1");        else if(n==3)puts("2");        else if(n==4)puts("24");        else if(n==5)puts("1344");        else if(n==6)puts("1128960");        else if(n==7)puts("12198297600");    }    return 0;}


 

13.一个二分题目,看到最大最小,基本就可以确定是二分了。。。有n个group,向m个箱子里面投票,问怎么投票,可以使得到的最多票的那个盒子票数最小。1013 选举主席

/*********************** author:crazy_石头* Pro:* algorithm:string* Time:0ms* Judge Status:Accepted***********************/#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <set>#include <stack>#include <string>using namespace std;#define LL long long#define rep(i,h,n) for(int i=(h);i<=(n);i++)#define ms(a,b) memset((a),(b),sizeof(a))#define INF 1<<29const int maxn=600000+5;const int maxm=100+5;const LL mod=10000007 ;int n,b,a[maxn];inline LL cal(LL x) {  LL ret=0;  rep(i,0,n-1)    ret+=(a[i]+x-1)/x;  return ret;}inline LL Binary(LL l, LL r){     while(l<=r)     {        LL mid=(l+r)>>1;        if(cal(mid)<=b)            r=mid-1;        else            l=mid+1;     }     return l;}int main(){    while(scanf("%d%d",&n,&b)!=EOF&&~n)    {        rep(i,0,n-1)scanf("%d",&a[i]);        printf("%d\n",Binary(0,INF));    }    return 0;}


 

 

原创粉丝点击