题解

POJ - 3617

题意: 从原串的头和尾部取字符,加到新串的尾部。让新 串的字典序最小,每80个字符换一次行。
思路: 要使字典序最小每个位置都取头和尾最小的那个加到新串的尾部,相等时则看头和尾谁能够将以后较小的字符更早的加入新串的尾部。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;

const int MN=2010;
char c[MN];

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0; i<n; i++)
    {
        getchar();
        scanf("%c",&c[i]);
    }
    int he=0,ta=n-1,sum=0;
    while(he<=ta)
    {
        sum++;
        if(c[he]<c[ta])
        {
            printf("%c",c[he]);
            he++;
        }
        else if(c[he]>c[ta])
        {
            printf("%c",c[ta]);
            ta--;
        }
        else
        {
            int i=he,j=ta;
            while(i<j && c[i]==c[j]) i++,j--;
            if(c[i]<=c[j])
            {
                printf("%c",c[he]);
                he++;
            }
            else
            {
                printf("%c",c[ta]);
                ta--;
            }
        }
        if(sum%80==0) printf("\n");
    }
    return 0;
}

POJ - 3253

题意: 将一整块木板切成N块长度各是Li的木板,切割一次的花费等于木板的长度,求最小总花费。
思路: 霍夫曼编码,用优先队列模拟。

#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;

int main()
{
    int n,t;
    priority_queue<int,vector<int>,greater<int> >Q;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&t);
        Q.push(t);
    }
    ll ans=0;
    while(Q.size()>1)
    {
        int d1=Q.top();
        Q.pop();

        int d2=Q.top();
        Q.pop();

        ans+=d1+d2;
        Q.push(d1+d2);
    }
    printf("%lld\n",ans);
    return 0;
}

POJ - 2689

题意: 给出区间 [L,R],求这个区间最相距最小,最大的素数对。
思路: 2到 sqrt N 内的素数 能把小于N的非素数全部标记,剩下的就是素数。先将10的6次方以内的素数打表,然后用这些素数将从L到R的非素数标记。

#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;

const int MN=1000010;
int g,p[MN];
bool vis[MN],bk[MN];
void prime()
{
    for(int i=2; i<MN; i++)
    {
        if(!vis[i]) p[++g]=i;
        for(int j=1; j<=g && i*p[j]<MN; j++)
        {
            vis[i*p[j]]=1;
            if(i%p[j]==0) break;
        }
    }
}


int main()
{
    prime();
    ll L,R;
    while(~scanf("%lld %lld",&L,&R))
    {
        memset(bk,0,sizeof(bk));
        if(L==1) bk[0]=1;
        for(int i=1; p[i]*p[i]<=R && i<=g; i++)
        {
            ll he;
            if(L%p[i]) he=(L/p[i]+1)*p[i];
            else he=L;
            if(he==p[i]) he+=p[i];
            for(ll j=he; j<=R; j+=p[i])
                bk[j-L]=1;
        }
        ll last=-1,mi=R,ma=0,mil,mir,mal,mar;
        for(ll i=L; i<=R; i++)
        {
            if(!bk[i-L])
            {
                if(last!=-1 && ma<i-last)
                {
                    ma=i-last;
                    mal=last;
                    mar=i;
                }

                if(last!=-1 && mi>i-last)
                {
                    mi=i-last;
                    mil=last;
                    mir=i;
                }
                last=i;
            }
        }
        if(mi==R) printf("There are no adjacent primes.\n");
        else printf("%lld,%lld are closest, %lld,%lld are most distant.\n",mil,mir,mal,mar);
    }
    return 0;
}

POJ - 1144

题目: 给出无向图,求割点的个数,模板题。

#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;

const int MN=110;
int g,fir[MN],nex[MN*MN],to[MN*MN];
void add(int x,int y)
{
    ++g;
    to[g]=y,nex[g]=fir[x],fir[x]=g;
}

int root,vis[MN];
int sum,num,dfn[MN],low[MN];
void tarjan(int u)
{
    int sbt=0;
    dfn[u]=low[u]=++num;
    for(int i=fir[u]; i; i=nex[i])
    {
        int du=to[i];
        if(!dfn[du])
        {
            sbt++;
            tarjan(du);
            low[u]=min(low[u],low[du]);
            if( (u==root && sbt>1 ) || (u!=root && dfn[u]<=low[du]) )
            {
                if(!vis[u])
                {
                    vis[u]=1;
                    sum++;
                }
            }
        }
        else low[u]=min(low[u],dfn[du]);
    }
}

int main()
{
    int n;
    while(~scanf("%d",&n)&&n)
    {
        g=sum=num=0;
        memset(fir,0,sizeof(fir));
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(vis,0,sizeof(vis));
        int t1,t2;
        while(~scanf("%d",&t1)&&t1)
        {
            char ch;
            while((ch=getchar())!='\n')
            {
                scanf("%d",&t2);
                add(t1,t2),add(t2,t1);
            }
        }
//        root=1;
//        tarjan(1);
        for(int i=1; i<=n; i++)
        {
            if(!dfn[i])
            {
                root=i;
                tarjan(i);
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}

HYSBZ - 1607

题意: 对于每头牛,求其他牛的纸条上数字是它的纸条上数因子的个数。

#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;

const int MN=1000010;
int a[MN],num[MN],cnt[MN];

int main()
{
    int N;
    while(~scanf("%d",&N))
    {
        memset(cnt,0,sizeof(num));
        memset(cnt,0,sizeof(cnt));
        for(int i=0; i<N; i++)
        {
            scanf("%d",&a[i]);
            num[a[i]]++;
        }
        for(int i=2; i<MN; i++)
        {
            if(num[i]==0) continue;
            for(int j=i; j<MN; j+=i)
                cnt[j]+=num[i];
        }
        for(int i=0; i<N; i++)
            printf("%d\n",cnt[a[i]]-1+num[1]);
    }
    return 0;
}

计蒜客 - T2013

快速幂模板

 
 #include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;

ll fpow(ll a,ll b,ll MD)
{
    ll ans=1,base=a;
    while(b)
    {
        if(b&1) ans=(ans*base)%MD;
        base=(base*base)%MD;
        b>>=1;
    }
    return ans;
}

int main()
{
    ll n,m,k,x;
    scanf("%lld %lld %lld %lld",&n,&m,&k,&x);
    printf("%lld\n",(m*fpow(10,k,n)%n+x)%n);
    return 0;
}

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值