2012天津网络赛

1001

 8进制数,直接贴代码。

 

#include <stdio.h>
int c[1000];
int fun(int t){
    int ret=0,mul=1;
    while (t!=0){
        ret+=mul*c[(t%10)];
        mul*=8;
        t/=10;
    }
    return ret;
}
int main(){
    c[0]=0;c[1]=1;c[2]=2;
    c[4]=3;c[5]=4;c[6]=5;c[7]=6;
    c[9]=7;
    int n,ret;
    while (scanf("%d",&n),n!=0){
        printf("%d: %d\n",n,fun(n));
    }



    return 0;
}


1002

找规律,注意观察平方数。这题不是我做的,木有代码

1003

可以当成很裸的网络流来做,Sap+Gap优化,木有模板怎么破~_~

 

#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
using namespace std;
const int N=2e5+10;
#define VM 100010
#define EM 400010
const int inf = 0x3f3f3f3f;
struct SAP{
    struct E
    {
        int to, frm, nxt, cap;
    }edge[EM];

    int head[VM],e,n,m;
    int dep[VM], gap[VM];
    void init(int _n=VM-10,int _m=EM-10)
    {
        memset(head,-1,sizeof(head));
        e=0;
        n=_n,m=_m;
    }

    void addedge(int cu, int cv, int cw)
    {
        edge[e].frm = cu;
        edge[e].to = cv;
        edge[e].cap = cw;
        edge[e].nxt = head[cu];
        head[cu] = e++;
        edge[e].frm = cv;
        edge[e].to = cu;
        edge[e].cap = 0;
        edge[e].nxt = head[cv];
        head[cv] = e++;
    }

    int que[VM];

    void BFS(int des)
    {
        memset(dep, -1, sizeof(dep));
        memset(gap, 0, sizeof(gap));
        gap[0] = 1;
        int front = 0, rear = 0;
        dep[des] = 0;
        que[rear++] = des;
        int u, v;
        while (front != rear)
        {
            u = que[front++];
            front = front%VM;
            for (int i=head[u]; i!=-1; i=edge[i].nxt)
            {
                v = edge[i].to;
                if (edge[i].cap != 0 || dep[v] != -1)
                    continue;
                que[rear++] = v;
                rear = rear % VM;
                ++gap[dep[v] = dep[u] + 1];
            }
        }
    }
    int cur[VM],stack[VM];
    int Sap(int src,int des)       //sap模板
    {
        int res = 0;
        BFS(des);
        int top = 0;
        memcpy(cur, head, sizeof(head));
        int u = src, i;
        while (dep[src] < n)
        {
            if (u == des)
            {
                int temp = inf, inser = n;
                for (i=0; i!=top; ++i)
                    if (temp > edge[stack[i]].cap)
                    {
                        temp = edge[stack[i]].cap;
                        inser = i;
                    }
                for (i=0; i!=top; ++i)
                {
                    edge[stack[i]].cap -= temp;
                    edge[stack[i]^1].cap += temp;
                }
                res += temp;
                top = inser;
                u = edge[stack[top]].frm;
            }

            if (u != des && gap[dep[u] -1] == 0)
                break;
            for (i = cur[u]; i != -1; i = edge[i].nxt)
                if (edge[i].cap != 0 && dep[u] == dep[edge[i].to] + 1)
                    break;

            if (i != -1)
            {
                cur[u] = i;
                stack[top++] = i;
                u = edge[i].to;
            }
            else
            {
                int min = n;
                for (i = head[u]; i != -1; i = edge[i].nxt)
                {
                    if (edge[i].cap == 0)
                        continue;
                    if (min > dep[edge[i].to])
                    {
                        min = dep[edge[i].to];
                        cur[u] = i;
                    }
                }
                --gap[dep[u]];
                ++gap[dep[u] = min + 1];
                if (u != src)
                    u = edge[stack[--top]].frm;
            }
        }
        return res;
    }
}g;

int main()
{
    int T,m,n,i,j,k,x,y,_s,_t,f,_min,_max;
    int res;
    scanf("%d",&T);
    while (T--)
    {
        _min=inf,_max=-inf;
        scanf("%d %d",&n,&m);
        g.init(n,m);
        for (i=1; i<=n; i++)
        {
            scanf("%d %d",&x,&y);
            if (x<_min) _min=x,_s=i;
            if (x>_max) _max=x,_t=i;
        }
        for (i=0; i<m; i++){
            scanf("%d %d %d",&x,&y,&f);
            g.addedge(x,y,f);
            g.addedge(y,x,f);
        }
//        printf("s=%d t=%d\n",_s,_t);
        if (_s==_t) res=0;else res=g.Sap(_s,_t);
        printf("%d\n",res);
    }

    return 0;
}


1005

数学题,只要确定y,z,就可以二分求出x。所以只要枚举yz就可以, y最多到sqrt(k),z<=31  300ms过

 

#include <stdio.h>
#include <cmath>
#include <map>
using namespace std;
//#define long long __int64
long long x,y,z,k,tot;
inline long long power(long long a,long long b){
    long long ret=1;
    for (int i=0;i<b;i++){
        ret*=a;
        if (ret>k) return (-1);
    }
    return ret;
}
int main(){
    while (scanf("%I64d",&k),k!=0){
        tot=0;
        for (z=2; z<=30; z++){
            for (y=2; y<=int(sqrt(k)) ; y++ ){
 //               printf("sqrt(%I64d)=%d\n",k,int(sqrt(k)) );
                long long l,r,t2=power(y,z);
                x=1;
                if (t2==-1) break;
//                printf("t2=%d ",t2);
                l=1;r=sqrt(k);
                while (l<=r){
                    x=(l+r)/2;
                    int t1=power(x,z);
                    if (t1==-1){
                        r=x-1;
                    }
                    else
                    if ( t1+t2+x*y*z>k ){
                        r=x-1;
                    }
                    else if ( t1+t2+x*y*z<k ){
                        l=x+1;
                    }
                    else {
//                        printf("$ok  ");
                        break;
                    }
                }
                if (x>=y) continue;
                int t1=power(x,z);
//                printf(" t1=%d ",t1);
//                printf("x=%d y=%d z=%d\n",x,y,z);
                if (t1!=-1)
                    if (t1+t2+x*y*z ==k){
//                        printf("x=%I64d y=%I64d z=%I64d\n",x,y,z);
                        tot++;
                    }
            }
        }
        printf("%I64d\n",tot);
    }


}


1006 

 DP  多边形剖分的变种,时间O(N^3) 空间O(N^2)

只要确定[i, j]中哪一个是最后出来的,就将区间分成2个子问题,dp[i][j]=MIN(dp[i][j],  dp[i][k-1]+dp[k+1][j]+(k-i)*(sum[j]-sum[k])+diaosi[k]*(j-i) );

#include <stdio.h>
#include <string.h>
#define NN 340
#define MIN(x,y) ( ( x ) < ( y )?( x ):( y ) )
int dp[NN][NN],sum[NN],diaosi[NN];
int n,T,i,j,k,l,cas=0;
void Readln(){

        memset(dp,7,sizeof(dp));
        memset(sum,0,sizeof(sum));
        scanf("%d",&n);
        for (int i=1;i<=n;i++){
            scanf("%d",&diaosi[i]);
            sum[i]=sum[i-1]+diaosi[i];
            dp[i][i]=0;
            dp[i][i-1]=dp[i+1][i]=0;
        }
}
void DP(){
    for (l=2; l<=n; l++){
        for (i=1; i<=n; i++){
            j=i+l-1;
            for (k=i; k<=j; k++){
                dp[i][j]=MIN(dp[i][j],
                    dp[i][k-1]+dp[k+1][j]+(k-i)*(sum[j]-sum[k])+diaosi[k]*(j-i) );
            }
        }
    }
}
int main(){
    scanf("%d",&T);
    while ( T-- ){
        Readln();
        DP();
        printf("Case #%d: %d\n",++cas,dp[1][n]);

    }

    return 0;
}


1007

  利用floyd求出最短路,然后忽略不要去的点,用H个点和起点终点组成一个新图,问题即转化为h=15的旅行商问题,dfs吧,500ms+

#include <stdio.h>
#include <string.h>
#define NN 220
struct ZCK{
    int num,c,d;
    bool used;
}need[NN];
int dis[NN][NN],g[NN][NN];
int visit[NN];
int n,m,money,h;
int fun(int now,int deep){
//    printf("now=%d  deep=%d money=%d\n",now,deep,money);
    int pos=need[now].num;
    if (deep==h) {
        if ( money-dis[pos][1]>=0 )  return 1;
        else return 0;
    }
    for (int i=1; i<h; i++)
      if ( visit[i]==0 ){
        int nextpos=need[i].num;
        visit[i]=1;
        if (money-dis[pos][nextpos]-need[i].d>=0){
            money+=(0-dis[pos][nextpos]-need[i].d+need[i].c);
            if ( fun(i,deep+1)==1 ) return 1;
            money-=(0-dis[pos][nextpos]-need[i].d+need[i].c);
        }
        visit[i]=0;
      }
    return 0;
}
void init(){
        memset(dis,7,sizeof(dis));
        memset(g,7,sizeof(g));
        memset(need,0,sizeof(need));
        memset(visit,0,sizeof(visit));
}
void floyed(){
    int i,j,k;
        for (k=1;k<=n;k++)
            for (i=1;i<=n;i++)
                for (j=1;j<=n;j++)
                    if (dis[i][k]+dis[k][j]<dis[i][j])
                        dis[i][j]=dis[i][k]+dis[k][j];
}
int main(){
    int T,i,j,k;
    int a,b,c;
    scanf("%d",&T);
    while (T--){
        scanf("%d %d %d",&n,&m,&money);
        init();
//        printf("$$$$%d\n",dis[0][0]);
        for (i=1;i<=n;i++) dis[i][i]=g[i][i]=0;
        for (i=1;i<=m;i++){
            scanf("%d %d %d",&a,&b,&c);
            if (g[a][b]>c){
                g[a][b]=g[b][a]=c;
                dis[a][b]=dis[b][a]=c;
            }
        }
        floyed();
        scanf("%d",&h);
        for (i=1;i<=h;i++){
            scanf("%d %d %d",&need[i].num,&need[i].c,&need[i].d);
        }
        need[0].num=1,need[0].c=0,need[0].d=0;
        visit[0]=1;
        h++;
        int ret=fun(0,1);
      //  printf("ret=%d\n",ret);
        if (ret==1){
            printf("YES\n");
        }
        else{
            printf("NO\n");
        }
/*        for (i=1;i<=n;i++)
        printf("1 to %d = %d\n",i,dis[1][i]);*/

    }


    return 0;
}


1010

简单题,将字符串转成int类型的数字,直接丢到map里面去+1, 询问的时候直接输出输入的数字在map里的计数就好了。(PS,这题队友做的,我觉得今天写的这个代码简单些)

 

#include <stdio.h>

#include <string>

#include <string.h>

#include <map>

using namespace std;

int ch[]={2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,

7,7,7,7,8,8,8,9,9,9,9};

int Q[5100];

int tonum(char *s){

    int ret=0;

    for (int i=0; i<strlen(s);i++)

        ret=ret*10+ch[s[i]-'a'];

    return ret;

}

int main(){

    int T,i,j,k,n,m,tmp,tot;

    scanf("%d",&T);

    map<int,int> ans;

    char buff[100];

    while (T--){

        ans.clear();

        scanf("%d %d",&n,&m);

        for (i=0; i<n; i++)

        {

            scanf("%d",&Q[i]);

        }

        for (i=0; i<m; i++){

            scanf("%s",buff);

            tmp=tonum(buff);

            ans[tmp]++;

//            printf("%s   %d\n",buff,tmp);

        }

        for (i=0; i<n; i++){

            printf("%d\n",ans[Q[i]]);

        }

    }

    return 0;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值