CSU 1991: Timo's mushrooms 1993: 大司马的三角形中单 1997: Seating Arrangement

1991: Timo's mushrooms

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=100010;
const int maxm=100010;
struct edge_t
{
    int v,next;
}edge[maxm],newedge[maxn];
int Ecnt,newEcnt;
int vertex[maxn],newvertex[maxn];
int Low[maxn],DFN[maxn],Stack[maxn],Belong[maxn];
int Index,top;
int scc;
bool Instack[maxn];
void init_Graph()
{
    Ecnt=newEcnt=0;
    memset(vertex,-1,sizeof(vertex));
    memset(newvertex,-1,sizeof(newvertex));
}
void make_edge(int u,int v)
{
    edge[Ecnt].v=v;
    edge[Ecnt].next=vertex[u];
    vertex[u]=Ecnt++;
}
void make_newedge(int u,int v)
{
    newedge[newEcnt].v=v;
    newedge[newEcnt].next=newvertex[u];
    newvertex[u]=newEcnt++;
}
void Tarjan(int u)
{
    int v;
    Low[u]=DFN[u]=++Index;
    Stack[top++]=u;
    Instack[u]=true;
    for(int i=vertex[u];i!=-1;i=edge[i].next)
    {
        v=edge[i].v;
        if(!DFN[v])
        {
            Tarjan(v);
            if(Low[u]>Low[v]) Low[u]=Low[v];
        }
        else if(Instack[v]&&Low[u]>DFN[v])
            Low[u]=DFN[v];
    }
    if(Low[u]==DFN[u])
    {
        scc++;
        do
        {
            v=Stack[--top];
            Instack[v]=false;
            Belong[v]=scc;
        }
        while(v!=u);
    }
}
void solve(int n)
{
    memset(DFN,0,sizeof(DFN));
    memset(Instack,false,sizeof(Instack));
    Index=scc=top=0;
    for(int i=1;i<=n;i++)
        if(!DFN[i])
           Tarjan(i);
}
int linker[maxn];
bool used[maxn];
bool dfs(int u)
{
    for(int i=newvertex[u];i!=-1;i=newedge[i].next)
    {
        int v=newedge[i].v;
        if(!used[v])
        {
            used[v]=true;
            if(linker[v]==-1||dfs(linker[v]))
            {
                linker[v]=u;
                return true;
            }
        }
    }
    return false;
}
int hungary()
{
    int res=0;
    memset(linker,-1,sizeof(linker));
    for(int u=1;u<=scc;u++)
    {
        memset(used,false,sizeof(used));
        if(dfs(u)) res++;
    }
    return res;
}
//缩点建立新图
void Build_newmap(int n)
{
    for(int u=1;u<=n;u++)
        for(int i=vertex[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(Belong[u]!=Belong[v])
                make_newedge(Belong[u],Belong[v]);
        }
}
int main()
{
    int t;
    int n,m;
    int u,v;
    scanf("%d",&t);
    while(t--)
    {
        init_Graph();
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&u,&v);
            make_edge(u,v);
        }
        solve(n);
        Build_newmap(n);
        printf("%d\n",scc-hungary());
    }
    return 0;
}

1993: 大司马的三角形中单

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

long long dp[13][10][2],num[13];

long long dfs(int len,int x,bool tp,bool lim)
{
    if (len==1) if (tp) return 0; else return 1LL;			//如果len为1,而且居然还是出现了转折点,那么显然转折点是其本身
    if (!lim&&dp[len][x][tp]>-1) return dp[len][x][tp];			//而这显然不合法故返回0,否则返回1有解
    long long res=0;
    if (tp)
    {
        int up=lim?num[len-1]:9;
        for(int i=x+1;i<=up;i++)
            res+=dfs(len-1,i,1,lim&&i==up);
        if (len>2)							//设前一位是转折点的情况,如此len-1必须大于1
            for(int i=x+1;i<=up;i++)
                res+=dfs(len-1,i,0,lim&&i==up);
    } else
    {
        long long up1=x==0?0:x-1;					//如果当前位置已经是0,那么上届是0而不是-1
        int up=lim?min(num[len-1],up1):up1;
        for(int i=0;i<=up;i++)
            res+=dfs(len-1,i,0,lim&&i==num[len-1]);
    }
    if (!lim) dp[len][x][tp]=res;
    return res;
}

long long cal(long long n)
{
    long long res=0,len=0;
    memset(dp,-1,sizeof(dp));
    while(n)
    {
        num[++len]=n%10;
        n/=10;
    }
    for(int i=3;i<=len;i++)					//枚举长度
    {
        int up=i==len?num[i]:9;
        for(int j=1;j<=up;j++)					//枚举第一位放的数字
            res+=dfs(i,j,1,i==len&&j==up);
    }
    return res;
}

int main()
{
    long long n,m;
    int T_T; scanf("%d",&T_T);
    while(T_T--)
    {
        scanf("%lld%lld",&n,&m);
        printf("%lld\n",cal(m)-cal(n-1));
    }
    return 0;
}

1997: Seating Arrangement

#include<stdio.h>
#include<string.h>
using namespace std;
int main()
{
    int i,j;
    int n,d;
    while(~scanf("%d%d",&n,&d))
    {
        if(d>n/2-1)
            printf("-1\n");
        else
        {
            int t = n/2;
            if(n%2)
                t = t+1;
                 
            for(i = t,j= 1;j<=n;j++)
            {
                if(i!=t) printf(" ");
                printf("%d",i);
                if(j%2) i = i + n/2;
                else i = i - (n/2+1);
            }
            printf("\n");
        }
    } 
    return 0;
} 


猜你喜欢

转载自blog.csdn.net/nameofcsdn/article/details/80455530