第三届 山东省ACM省赛

Solved ID PID Title Accepted Submit
  A 2407 Impasse (+) 0 0
  B 2410 Mine Number 3 19
  C 2412 Fruit Ninja I 4 19
  D 2414 An interesting game 1 6
  E 2416 Fruit Ninja II 8 13
  F 2415 Chess 1 1
  G 2413 n a^o7 ! 10 14
  H 2411 Pixel density 9 36
  I 2409 The Best Seat in ACM Contest 10 20
  J 2408 Pick apples 7 45

A Impasse (+)

:http://www.sdutacm.org/sdutoj/showproblem.php?pid=2407&cid=1744


B:Mine Number

http://www.sdutacm.org/sdutoj/problem.php?action=showproblem&problemid=2410

只要是第一行确定了,全部棋局也就确定了,dfs搜索第一行的情况,然后后面的直接根据上一行而定,这样最后就能得出整个矩阵了,第一行最多20个,也就是复杂度为2^20,不会超时,并且中间还会有剪枝。

但是苦逼的是当时模拟的时候感觉dfs没什么用,只要第一行确定了其他就能确定的话,我直接二进制分解获得第一行就行了,但是这样做了好久,却不是TL就是WR,至今不知道为何,以后有时间了再看吧。。。(顺便也贴下第一次二进制分解的错误方法。。)

#include <iostream>  
#include <cstdio>  
#include <string>  
#include <cstring>  
#define MAX 500  
using namespace std;  
char ch[100][100],res[100][100];  
int T,n,m;  
int dir[][2]= {{-1,0},{1,0},{0,-1},{0,1},{0,0}};  
int mark=0;  
  
bool OK(int x,int y){  
  int tempx,tempy;  
  for(int i=0;i<5;i++){  
    tempx=x+dir[i][0],tempy=y+dir[i][1];  
    if( (tempx<0 || tempx>=n || tempy<0 || tempy>=m) || ch[tempx][tempy]>='1')  
        continue;  
    else return false;  
  }  
  return true;  
}  
  
void update(int x,int y,int num){  
  for(int i=0;i<4;i++){  
     int tempx=dir[i][0]+x , tempy=dir[i][1]+y;  
          if( tempx >= 0 && tempx < n && tempy>=0 &&tempy<m )  
              ch[tempx][tempy]+=num;  
    }  
  ch[x][y]+=num;  
}  
  
  
void printres(){  
  for(int i=0; i<n; i++)  
    {  
        for(int j=0; j<m; j++)  
            printf("%c",res[i][j]);  
        printf("
");  
    }  
}  
  
  
bool judge(){  
  for(int i=0;i<m;i++)  
    if(ch[n-1][i]!='0')  
      return false;  
  return true;  
}  
  
void dfs(int x,int y){  
  if(y>=m) x++,y=0;  
  if( x==n && y==0 ){  
    if(judge()){  
        printres();  
        mark=1;  
    }  
  }  
  if( x<0 || x>=n || mark==1) return ;  
  if(x==0){  
      if( OK(x,y) ){  
            update(x,y,-1);  
            res[x][y]='*';  
            dfs(x,y+1);  
            update(x,y,1);  
            res[x][y]='?';  
      }  
      res[x][y]='.';  
      dfs(x,y+1);  
    return ;  
  }  
  
  if( ch[x-1][y] !='0' && ch[x-1][y] !='1' )  
    return ;  
  if(ch[x-1][y]=='1'){  
    res[x][y]='*';  
    update(x,y,-1);  
    dfs(x,y+1);  
    update(x,y,1);  
    res[x][y]='?';  
  }  
else{
  res[x][y]='.';  
  dfs(x,y+1); 
} 
  return ;  
}  
  
  
int main ()  
{  
    char dev[100];  
    int coun=1;  
    scanf("%d",&T);  
    while(T--)  
    {  
        mark=0;  
        scanf("%d%d",&n,&m);  
        for(int i=0; i<n; i++)  
            scanf("%s",&ch[i]);  
        printf("Case %d:
",coun++);  
        dfs(0,0);  
    }  
  
    return 0;  
} 


二进制分解
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#define MAX 500
using namespace std;
char ch[100][100],temp[100][100],res[100][100];
int T,n,m;
int dir[][2]= {{-1,0},{1,0},{0,-1},{0,1}};

bool Ok(int tempm){
  return temp[0][tempm]=='0' || (tempm!=0&&temp[0][tempm-1]=='0') || (tempm+1<m&&temp[0][tempm+1]=='0'); ///|| (1<n&&temp[1][tempm]=='0')
}


int main ()
{
    char dev[100];
    int coun=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0; i<n; i++)
            scanf("%s",&ch[i]);
        int x=(1<<m);
        printf("Case %d:
",coun++);
        int last=n-1;
        for(int ss=x-1; ss>=0; ss--)
        {
            int mark=1;
            int tempm=m-1;
            for(int j=0; j<m; j++)
                res[0][j]='.';
            for(int i=0; i<=n-1; i++)
                strcpy(temp[i],ch[i]);

            int tempss=ss;
            for(; tempss>0; tempm--)
            {
                if(tempss%2)
                {
                    res[0][tempm]='*';
                    if(Ok(tempm))
                    {
                        mark = 0;
                        last=2;
                        break;
                    }
                    temp[0][tempm]--;
                    if(tempm-1>=0) temp[0][tempm-1]--;
                    if(tempm+1<m) temp[0][tempm+1]--;
                    if(1<n) temp[1][tempm]--;
                }
                tempss/=2;
            }

            for(int i=1; i<n  &&  mark  ; i++)
                for(int j=0; j<m  &&  mark; j++)
                {
                    if( temp[i-1][j]!='0' && temp[i-1][j]!='1' )
                    {
                        mark=0;
                        last=min(n-1,i+2);
                        break;
                    }
                    res[i][j]='.';
                    if(temp[i-1][j]=='1')
                    {
                        res[i][j]='*';
                        for(int xxx=0; xxx<4; xxx++)
                            if(i+dir[xxx][0]>=0 && i+dir[xxx][0]<m && j+dir[xxx][1]>=0  && j+dir[xxx][1]<m)
                            {
                                if(temp[  i+dir[xxx][0]  ][ j+dir[xxx][1] ]<='0')
                                {
                                    mark=0;
                                    last=min(n-1,i+2);
                                    break;
                                }
                                temp[  i+dir[xxx][0]  ][ j+dir[xxx][1] ]--;
                            }
                        temp[i][j]--;
                    }
                }
            if(mark==1)
            {
                for(int i=0; i<m&&mark; i++) ///判断最后一行
                    if(temp[n-1][i]!='0')
                        mark=0,last=n-1;

                for(int i=0; i<n&&mark; i++)
                {
                    for(int j=0; j<m; j++)
                        printf("%c",res[i][j]);
                    printf("
");
                }
                if(mark){
                   break;
                }
            }
        }
    }

    return 0;
}




CFruit Ninja I

 http://www.sdutacm.org/sdutoj/problem.php?action=showproblem&problemid=2412

题意:一个切水果游戏。每秒出现一些水果,它们都在一条线上,有好水果和坏水果,好的可以加分,坏的减分,每次连续切好水果三个以上可以分数加倍。每秒只能切一次,每切一次要间隔m秒。问最多得多少分。

暴力+dp 开始的时候没想到,没什么头绪,因为每一次需要间隔一定的时间,但是没考虑到每个时间点t内的最大值是可求得,这样直接DP就好了。。。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<ctime>
#define eps 1e-6
#define MAX 10010
#define INF 0x3f3f3f3f
#define LL long long
#define pii pair<string,int>
#define rd(x) scanf("%d",&x)
#define rd2(x,y) scanf("%d%d",&x,&y)
using namespace std;
struct Stru{
  int time;
  int x;
  int mm;
}pos[MAX];
int arr[MAX];
int dp[MAX];

bool cmp(Stru a,Stru b){
  if(a.time!=b.time) return a.time<b.time;
  return a.x<b.x;
}

int main()
{
   int T;
   scanf("%d",&T);
   int n,m,temp,Case=1;
   while(T--){
      scanf("%d%d",&n,&m);
      for(int i=0;i<n;i++){
        scanf("%d%d%d",&pos[i].time,&temp,&pos[i].x);
        pos[i].mm = ( temp == 0 ? 1 : -1);
      }
      memset(arr,0,sizeof(arr));
      sort(pos,pos+n,cmp);
      
      
      int start=pos[0].time,sum=0,seque=0,mmax=0;///start:当前正在判断的时间标志
                                                 ///sum:在start秒里到当前位置能获得的最大的分数
                                                 ///     注意!如果seque统计需要加倍时在seque清0之前是没有Double分数的)
                                                 ///seque:连续的个数(用来最后统计Double分数的)
                                                 ///mmax:当前秒获得的最大分数
                                                 
      ///该部分统计分数的精髓:http://blog.csdn.net/u014665013/article/details/50094365
      for(int i=0;i<n;i++){ ///暴力求每个时间t能获得的最大分数(连续区间最大值)
        if(pos[i].time==start){
           if(pos[i].mm==-1){
              if(seque>=3) sum+=seque;
              seque=0;
           }
           else seque++;
           
           sum += pos[i].mm;
           if ( sum+(seque>=3?seque:0) > mmax)
              mmax = sum+(seque>=3?seque:0);
           else if (sum < 0)
              sum = 0;
        }
        else{
            arr[ pos[i-1].time ] = mmax;
            start=pos[i].time;
            sum=0,seque=0;
            if(pos[i].mm==1)
               sum=1,seque=1;
            mmax=sum;
        }
      }
      arr[pos[n-1].time]=mmax;

      dp[0]=0;
      for(int i=1;i<=pos[n-1].time;i++){  ///dp最大值 转移方程 dp[i]=dp[i-1],dp[i-m-1]+arr[i]
        if(i>m+1)
            dp[i]=max(dp[i-1],dp[i-m-1]+arr[i]);
        else
            dp[i]=max(dp[i-1],arr[i]);
      }
      printf("Case %d: %d
",Case++,dp[pos[n-1].time]);
   }
   return 0;
}


D  An interesting game

http://www.sdutacm.org/sdutoj/showproblem.php?pid=2414&cid=1744

最小费用最大流,开始ps用贪心,每次找出最大高度或者最小高度的插入,然后如果最大高度的能插入则插最大的,否则就插小的,(注意插入时候需要贪心两步)感觉是可以的,但是最终问题出在哪里好像还不知道。

一个不错的网址:http://www.hardbird.net/%E5%B1%B1%E4%B8%9C%E7%9C%81%E7%AC%AC%E4%B8%89%E5%B1%8A%E7%9C%81%E8%B5%9B-c-%E9%A2%98-an-interesting-game%E8%B4%B9%E7%94%A8%E6%B5%81/

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int maxn=2200;
const int oo=0x3f3f3f3f;
struct Edge
{
    int u, v, cap, flow, cost;Edge(){}
    Edge(int u, int v, int cap, int flow, int cost):u(u), v(v), cap(cap), flow(flow), cost(cost) {}
};
struct MCMF
{
    int n, m, s, t;
    vector<Edge> edge;
    vector<int> G[maxn];
    int inq[maxn], d[maxn], p[maxn], a[maxn];
    void init(int n)
    {
        this->n=n;
        for(int i=0; i<n; i++)
            G[i].clear();
        edge.clear();
    }
    void AddEdge(int u, int v, int cap, int cost)
    {
        edge.push_back(Edge(u, v, cap, 0, cost));
        edge.push_back(Edge(v, u, 0, 0, -cost));
        m=edge.size();
        G[u].push_back(m-2);
        G[v].push_back(m-1);
    }
    bool spfa(int s, int t, int& flow, int& cost)
    {
        memset(d, 0x3f, sizeof d);
        memset(inq, 0, sizeof inq);
        d[s]=0, inq[s]=1, p[s]=0, a[s]=oo;

        queue<int> q;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            inq[u]=0;
            for(int i=0; i<G[u].size(); i++)
            {
                Edge& e=edge[G[u][i]];
                if(e.cap>e.flow && d[e.v]>d[u]+e.cost)
                {
                    d[e.v]=d[u]+e.cost;
                    p[e.v]=G[u][i];
                    a[e.v]=min(a[u], e.cap-e.flow);
                    if(!inq[e.v])
                    {
                        q.push(e.v);
                        inq[e.v]=1;
                    }
                }
            }
        }
        if(d[t]==oo)return false;
        flow+=a[t];
        cost+=d[t]*a[t];
        int u=t;
        while(u!=s)
        {
            edge[p[u]].flow+=a[t];
            edge[p[u]^1].flow-=a[t];
            u=edge[p[u]].u;
        }
        return true;
    }
    int MinCost(int s, int t)
    {
        int flow=0, cost=0;
        while(spfa(s, t, flow, cost));
        return cost;
    }
} net;

int a[maxn], b[maxn];

int main()
{
    int T, kase=0;
    scanf("%d", &T);
    while(T--)
    {
        int n, m, k, ans=0;
        scanf("%d%d%d", &n, &m, &k);
        net.init(n+100);
        memset(b, 0, sizeof b);
        for(int i=0; i<n; i++)
            scanf("%d", a+i);
        for(int i=0; i<m; i++)
        {
            int x;
            scanf("%d", &x);
            b[x]++;
        }
        for(int i=1; i<n; i++)
        {
            ans+=abs(a[i]-a[i-1]);
            net.AddEdge(0, i, 1, 0);
            for(int j=0; j<=30; j++)
                if(b[j])
                {
                    int dis=abs(a[i]-j)+abs(a[i-1]-j)-abs(a[i]-a[i-1]);
                    net.AddEdge(i, n+j, 1, -dis);
                }
        }
        int S=n+50, T=S+1;
        for(int i=0; i<=30; i++)
            if(b[i])
                net.AddEdge(i+n, T, b[i], 0);
        net.AddEdge(S, 0, k, 0);
        printf("Case %d: %d
", ++kase, ans-net.MinCost(S, T));
    }
    return 0;
} 


另一个

/*
SPFA版费用流
最小费用最大流,求最大费用最大流只需要取相反数,结果取相反数即可。
点的总数为N,点的编号0~N-1
*/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;

const int MAXN=1500;
const int MAXM=80000;
const int INF=0x3f3f3f3f;
struct Edge{
    int to,next,cap,flow,cost;
}edge[MAXM];
int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN];
int N;//节点总个数,节点编号从0~N-1
void init(int n){
    N=n;
    tol=0;
    memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int cap,int cost){
    edge[tol].to=v;
    edge[tol].cap=cap;
    edge[tol].cost=cost;
    edge[tol].flow=0;
    edge[tol].next=head[u];
    head[u]=tol++;
    edge[tol].to=u;
    edge[tol].cap=0;
    edge[tol].cost=-cost;
    edge[tol].flow=0;
    edge[tol].next=head[v];
    head[v]=tol++;
}
bool spfa(int s,int t){
    queue<int>q;
    for(int i=0;i<N;i++){
        dis[i]=INF;
        vis[i]=false;
        pre[i]=-1;
    }
    dis[s]=0;
    vis[s]=true;
    q.push(s);
    while(!q.empty()){
        int u=q.front();
        q.pop();
        vis[u]=false;
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost){
                dis[v]=dis[u]+edge[i].cost;
                pre[v]=i;
                if(!vis[v]){
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
    }
    if(pre[t]==-1)return false;
    else return true;
}
//返回的是最大流,cost存的是最小费用
int minCostMaxflow(int s,int t,int &cost){
    int flow=0;
    cost=0;
    while(spfa(s,t)){
        int Min=INF;
        for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]){
            if(Min>edge[i].cap-edge[i].flow)
                Min=edge[i].cap-edge[i].flow;
        }
        for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]){
            edge[i].flow+=Min;
            edge[i^1].flow-=Min;
            cost+=edge[i].cost*Min;
        }
        flow+=Min;
    }
    return flow;
}

int main(){

    int T;
    int N2,M,K;
    int X[1005],Y[1005];
    int YNum[40];
    int i,j;
    int sp,sp2;//源点,源点2
    int sc;//汇点
    int sum;
    int tmp;
    int mi_cost;
    int ma_flow;
    int ca=0;

    scanf("%d",&T);

    while(T--){

        scanf("%d%d%d",&N2,&M,&K);

        init(N2+50);

        for(i=0;i<N2;++i){
            scanf("%d",&X[i]);
        }
        memset(YNum,0,sizeof(YNum));
        for(i=0;i<M;++i){
            scanf("%d",&Y[i]);
            ++YNum[Y[i]];
        }

        sum=0;
        for(i=0;i<N2-1;++i){//初始值
            sum=sum+abs(X[i]-X[i+1]);
        }

        sp=N2+40;

        for(i=0;i<N2-1;++i){//加边
            addedge(sp,i,1,0);//源点到空隙
            for(j=0;j<=30;++j){
                if(YNum[j]){
                    tmp=abs(X[i]-j)+abs(X[i+1]-j)-abs(X[i]-X[i+1]);
                    addedge(i,N2+j,1,-tmp);//空隙到M个山丘
                }
            }
        }

        sp2=N2+41;
        sc=N2+42;
        addedge(sp2,sp,K,0);
        for(i=0;i<=30;++i){
            if(YNum[i]){
                addedge(N2+i,sc,YNum[i],0);
            }
        }

        ma_flow=minCostMaxflow(sp2,sc,mi_cost);

        printf("Case %d: %d
",++ca,sum-mi_cost);
    }

    return 0;
}



#include <iostream>  
#include <stdio.h>  
#include <cmath>  
using namespace std;  
  
int main()  
{  
    int T;  
    scanf("%d",&T);  
    int i;  
    for(i=1;i<=T;i++)  
    {  
        int a,b,h;  
        scanf("%d%d%d",&a,&b,&h);  
        double V;  
        V=(4.0/3)*M_PI*a*b*b;  
        if(h>=b)  
        {  
            printf("Case %d: %.3lf
",i,V);  
        }  
        else  
        {  
            double v=M_PI*a*b*(b-h)-M_PI*(1.0*a/b)*(1.0/3)*(b*b*b-h*h*h);  
            if(V-v-v>0)  
            printf("Case %d: %.3lf
",i,V-v);  
            else  
            printf("Case %d: %.3lf
",i,v);  
        }  
    }  
    return 0;  
}  


E:Fruit Ninja II 

#include <iostream>  
#include <stdio.h>  
#include <cmath>  
using namespace std;  
  
int main()  
{  
    int T;  
    scanf("%d",&T);  
    int i;  
    for(i=1;i<=T;i++)  
    {  
        int a,b,h;  
        scanf("%d%d%d",&a,&b,&h);  
        double V;  
        V=(4.0/3)*M_PI*a*b*b;  
        if(h>=b)  
        {  
            printf("Case %d: %.3lf
",i,V);  
        }  
        else  
        {  
            double v=M_PI*a*b*(b-h)-M_PI*(1.0*a/b)*(1.0/3)*(b*b*b-h*h*h);  
            if(V-v-v>0)  
            printf("Case %d: %.3lf
",i,V-v);  
            else  
            printf("Case %d: %.3lf
",i,v);  
        }  
    }  
    return 0;  
}  


F:Chess



G:n a^o7 !

#include <iostream>  
#include <cstdio>  
#include <string>  
#include <cstring>  
#define MAX 500  
using namespace std;  
int main (){  
 char temp1[MAX],temp2[MAX],str[MAX];  
 strcpy(temp1," n5!wpuea^o7!usimdnaevoli");  
 strcpy(temp2," usimdnaevolin5!wpuea^o7!");  
 int Len = strlen(temp1);  
 int T;  
 scanf("%d",&T);  
 getchar();  
 int coun=1;  
 while(T--){  
   gets(str);  
   int len=strlen(str);  
   for(int i=0,j=0;i<len;i++){  
    for(j=0;j<Len;j++)  
       if(str[i]==temp1[j])  
          break;  
     if(j<Len) str[i]=temp2[j];  
   }  
   printf("Case %d: ",coun++);  
   for(int i=len-1;i>=0;i--)  
     printf("%c",str[i]);  
   printf("
");  
 }  
return 0;  
}  
  


H:Pixel density

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std;

char str[12345];

char str1[12345];
char str2[12345];

char num1[12345];
char num2[12345];
char num3[12345];

int main(){

    int T;
    int i;
    int len;
    int len1,len2;
    int p1,p2;
    int p3,p4;
    int len_num1,len_num2,len_num3;
    int j;
    double a,a1,a2,b,b1,b2,c,c1,c2;
    int p5;
    double Dp;
    double ans;
    int ca=0;
    int p6,p7;

    scanf("%d",&T);
    getchar();
    //scanf("%[^
]",str);
    //cout<<str<<endl;

    while(T--){
        scanf("%[^
]",str);
        getchar();
        //printf("");
        //printf("%s
",str);
        //cout<<str<<endl;
        len=strlen(str);
        //cout<<len<<endl;

        len1=0;
        len2=0;
        len_num1=0;
        len_num2=0;
        len_num3=0;

        for(i=0;i<len;++i){
            if(str[i]=='i'){
                if(str[i+1]=='n'&&str[i+2]=='c'&&str[i+3]=='h'&&
                   str[i+4]=='e'&&str[i+5]=='s'&&str[i+6]==' '){
                       p1=i;
                       j=i-1;
                       while(str[j]==' '){
                            --j;
                       }
                       while(str[j]!=' '){
                            num1[len_num1++]=str[j--];
                       }
                       while(str[j]==' '){
                            --j;
                       }
                       p3=j;
                   }
            }
            if(str[i]=='*'){
                if(i>=1&&'0'<=str[i-1]&&str[i-1]<='9'){
                    if('0'<=str[i+1]&&str[i+1]<='9'){
                        p2=i;
                        j=i-1;
                        while(str[j]!=' '){
                            num2[len_num2++]=str[j--];
                        }

                        j=i+1;
                        while(str[j]!=' '){
                            num3[len_num3++]=str[j++];
                        }

                        while(str[j]==' '){
                            ++j;
                        }
                        p4=j;
                    }
                }
            }

        }

        for(i=0;i<=p3;++i){
            if(str[i]!=' '){
                break;
            }
        }
        str1[len1++]=str[i++];
        for(;i<=p3;++i){
            if(str[i]==' '&&str1[len1-1]==' '){
                continue;
            }
            str1[len1++]=str[i];
        }
        str1[len1]='';


        for(i=p4;i<len;++i){
            if(str[i]==' '&&str2[len2-1]==' '){
                continue;
            }
            if('a'<=str[i]&&str[i]<='z'){
                str2[len2++]=str[i];
            }
            else if('A'<=str[i]&&str[i]<='Z'){
                str2[len2++]=str[i]+32;
            }
            else{
                str2[len2++]=str[i];
            }

        }
        str2[len2]='';

        for(i=len2-1;i>=0;--i){
            if(str2[i]!=' '){
                len2=i+1;
                break;
            }
        }
        str2[i+1]='';

/*
        cout<<str1<<endl;
        cout<<str2<<endl;
        cout<<num1<<endl;
        cout<<num2<<endl;
        cout<<num3<<endl;
        */

        p5=-1;
        for(i=0;i<len_num1;++i){
            if(num1[i]=='.'){
                p5=i;
                break;
            }
        }
        a=0;
        a1=0;
        a2=0;
        if(p5==-1){
            for(i=0;i<len_num1;++i){
                a1=a1+(num1[i]-'0')*pow(10,i);
            }
        }
        else{
            //a2=0;
            for(i=0;i<p5;++i){
                a2=a2/10+(num1[i]-'0')/10.0;
            }
            //a1=0;
            for(i=p5+1;i<len_num1;++i){
                a1=a1+(num1[i]-'0')*pow(10,(i-(p5+1)));
            }
        }


        //cout<<a2<<endl;
        //cout<<a1<<endl;
        a=a1+a2;

        //cout<<"a:"<<a<<endl;
        if(a==0){
            printf("Case %d: The %s of %s's PPI is %.2f.
",++ca,str2,str1,0.0);
            continue;
        }

        p6=-1;
        for(i=0;i<len_num2;++i){
            if(num2[i]=='.'){
                p6=i;
                break;
            }
        }
        if(p6==-1){
            b=0;
            for(i=0;i<len_num2;++i){
                b=b+(num2[i]-'0')*pow(10,i);
            }
        }
        else{
            b=0;
            b1=0;
            b2=0;
            //cout<<p6<<"***"<<endl;
            for(i=0;i<p6;++i){
                b2=b2/10+(num2[i]-'0')/10.0;
                //cout<<"##"<<b2<<endl;
            }
            for(i=p6+1;i<len_num2;++i){
                b1=b1+(num2[i]-'0')*pow(10,(i-(p6+1)));
            }
            /*
            for(i=p5-1;i>=0;--i){
                a2=a2/10+(num1[i]-'0')/10.0;
            }
            //a1=0;
            for(i=p5+1;i<len_num1;++i){
                a1=a1+(num1[i]-'0')*pow(10,(i-(p5+1)));
            }
            */
            b=b1+b2;

            //cout<<"b:"<<b<<endl;
        }


        p7=-1;
        for(i=0;i<len_num3;++i){
            if(num3[i]=='.'){
                p7=i;
                break;
            }
        }
        if(p7==-1){
            c=0;
            for(i=0;i<len_num3;++i){
                c=c*10+(num3[i]-'0');
            }
        }
        else{
            c=0;
            c1=0;
            c2=0;
            for(i=0;i<p7;++i){
                //c2=c2/10+(num3[i]-'0')/10.0;
                c1=c1*10+(num3[i]-'0');
                //cout<<"##"<<c2<<endl;
            }
            for(i=p7+1;i<len_num3;++i){
                //c1=c1+(num3[i]-'0')*pow(10,(i-(p7+1)));
                c2=c2/10+(num3[i]-'0')/10.0;
            }

            c=c1+c2;

            //cout<<"c:"<<c<<endl;
        }


        //cout<<b<<endl;
        //cout<<c<<endl;

        Dp=sqrt(b*b+c*c);
        ans=Dp/a;

        //cout<<ans<<endl;

        printf("Case %d: The %s of %s's PPI is %.2f.
",++ca,str2,str1,ans);
    }
    /*
    33
    ip 00300.00600 inches 00500.00600*00700.00800 IPHone


2
iPhone 4S  3.5 inches 960*640 PHONE
The new iPad  0009.7 inches 2048*1536 PAD


    */

    return 0;
}




I:The Best Seat in ACM Contest

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int main(){

    int T;
    int N,M;
    int s[25][25];
    int v[25][25];
    int i,j;
    int a,b;
    int ma,ma_i,ma_j;
    int ca=0;
    int k;

    scanf("%d",&T);

    while(T--){
        scanf("%d%d",&N,&M);

        for(i=0;i<N;++i){
            for(j=0;j<M;++j){
                scanf("%d",&s[i][j]);
            }
        }

        memset(v,0,sizeof(v));

        for(i=0;i<N;++i){
            for(j=0;j<M;++j){
                for(k=0;k<4;++k){
                    a=i+dir[k][0];
                    b=j+dir[k][1];
                    if(a<0||b<0||a>=N||b>=M){
                        v[i][j]-=1;
                        continue;
                    }
                    if(s[a][b]>s[i][j]){
                        v[i][j]=v[i][j]+(s[a][b]-s[i][j]);
                    }
                    else{
                        v[i][j]=v[i][j]-(s[i][j]-s[a][b]);
                    }
                }
            }
        }

        ma=v[0][0];
        ma_i=0;
        ma_j=0;
        for(i=0;i<N;++i){
            for(j=0;j<M;++j){
                if(v[i][j]>=ma){
                    ma=v[i][j];
                    ma_i=i;
                    ma_j=j;
                }
            }
        }

        printf("Case %d: %d %d %d
",++ca,ma,ma_i+1,ma_j+1);
    }

    return 0;
}


/**************************************
	Problem id	: SDUT OJ I 
	User name	: 666777 
	Result		: Accepted 
	Take Memory	: 512K 
	Take Time	: 0MS 
	Submit Time	: 2016-04-30 13:53:18  
**************************************/


J:Pick apples

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;

struct node{
    long long S;
    long long P;
    double q;
}a[3];

bool cmp(node a,node b){
    return a.q>b.q;
}

int main(){

    int T;
    long long V;
    long long sum;
    long long dp[6000];
    long long tmp;
    int i,j;
    int ca=0;


    scanf("%d",&T);

    while(T--){
        scanf("%lld%lld",&a[0].S,&a[0].P);
        a[0].q=(double)(a[0].P)/a[0].S;
        //cout<<a[0].q<<endl;
        scanf("%lld%lld",&a[1].S,&a[1].P);
        a[1].q=(double)(a[1].P)/a[1].S;
        //cout<<a[1].q<<endl;
        scanf("%lld%lld",&a[2].S,&a[2].P);
        a[2].q=(double)(a[2].P)/a[2].S;
        //cout<<a[2].q<<endl;
        scanf("%lld",&V);

        sort(a,a+3,cmp);

        sum=V%a[0].S;

        for(i=1;;++i){
            if(a[0].S*i>=5000){
                break;
            }
        }

        sum=sum+a[0].S*i;

        memset(dp,0,sizeof(dp));

        for(i=0;i<3;++i){
            for(j=a[i].S;j<=sum;++j){
                tmp=dp[j-a[i].S]+a[i].P;
                if(tmp>dp[j]){
                    dp[j]=tmp;
                }
            }
        }

        for(i=sum;;--i){
            if(dp[i]>0){
                break;
            }
        }

        printf("Case %d: %lld
",++ca,((V-sum)/a[0].S)*a[0].P+dp[i]);

    }

    return 0;
}


/**************************************
	Problem id	: SDUT OJ J 
	User name	: 666777 
	Result		: Accepted 
	Take Memory	: 556K 
	Take Time	: 0MS 
	Submit Time	: 2016-04-30 17:44:39  
**************************************/


原文地址:https://www.cnblogs.com/zswbky/p/6718005.html