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

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<<29

const 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<<29

const 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<<29

const 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<<29

const 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<<29

const 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<<29

const 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;
}


 

 

你可能感兴趣的:(2013 大连海事大学腾讯马拉松 div2第一场部分题解)