校赛酱油记~~~

 

1001(hdu5948 Thickest Burger )

src:http://acm.hdu.edu.cn/showproblem.php?pid=5948

#include <iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<functional>
#include<utility>
#include<string>
#include<string.h>
#include<vector>
using namespace std;

int main()
{
    int cas,a,b;
    cin>>cas;
    while(cas--){
        cin>>a>>b;
        if(a>b){
            cout<<a*2+b<<endl;
        }
        else cout<<b*2+a<<endl;
    }
    return 0;
}
View Code

1002(hdu5982 Relic Discovery)

src:http://acm.hdu.edu.cn/showproblem.php?pid=5982

#include <iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<functional>
#include<utility>
#include<string>
#include<string.h>
#include<vector>
using namespace std;

int main()
{
    int cas,a,b,t;
    cin>>cas;
    while(cas--){
        int ans=0;
        cin>>t;
        while(t--){
            cin>>a>>b;
            ans+=a*b;
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

1003(hdu 1171 Big Event in HDU)

src:http://acm.hdu.edu.cn/showproblem.php?pid=1171

这题有个诡异的八阿哥,就是以负数作为结束,而不只是-1,然后这是一道多重背包问题,总价值尽可能平均分两部分,小的那部分就是小于等于sum/2,所以取背包容量就是总价值的一半。这题拆成01背包也能暴力过,评测姬结果是01背包967ms,用多重背包写是109ms.

01背包 

#include <iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<functional>
#include<utility>
#include<string>
#include<string.h>
#include<vector>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
int n,half,sum,ans,ad;
int v[55],num[55],dp[2500000];
int main()
{
    std::ios::sync_with_stdio(false);
    while(cin>>n&&n>=0){
        cnt=0;
        half=sum=ans=0;
        FOR(i,1,n){
            cin>>v[i]>>num[i];
            sum+=v[i]*num[i];
        }
        half=sum/2;
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++){
            for(int j=1;j<=num[i];j++){

                for(int k=v[i];k<=half;k++){
                    dp[k]=max(dp[k],dp[k-v[i]]+v[i]);
                }
            }
        }
        ans=dp[half];
        int tmp=sum-ans;
        cout<<tmp<<' '<<ans<<endl;
    }
    return 0;
}
View Code

多重背包 //使用滚动数组时一定要从大的状态滚起,这样才能保证前面的状态是上一个阶段的!!!

#include <iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<functional>
#include<utility>
#include<string>
#include<string.h>
#include<vector>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
int n,half,sum,ans,ad;
int v[55],num[55],dp[2500000];
int val[600],cnt;
int main()
{
    std::ios::sync_with_stdio(false);
    while(cin>>n&&n>=0){
        cnt=0;
        half=sum=ans=0;
        FOR(i,1,n){
            cin>>v[i]>>num[i];
            sum+=v[i]*num[i];
        }
        half=sum/2;
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++){
            for(int j=1;num[i]>0;j*=2){
                int x=min(j,num[i]);
                val[cnt++]=v[i]*j;
                num[i]-=x;
            }
        }
        for(int i=0;i<cnt;i++){
            for(int k=half;k>=val[i];k--){//使用滚动数组时一定要从大的状态滚起,这样才能保证前面的状态是上一个阶段的!!!
                dp[k]=max(dp[k],dp[k-val[i]]+val[i]);
            }
        }
        ans=dp[half];
        int tmp=sum-ans;
        cout<<tmp<<' '<<ans<<endl;
    }
    return 0;
}
View Code

1004(hdu2952Counting Sheep)

src:http://acm.hdu.edu.cn/showproblem.php?pid=2952

#include <iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<functional>
#include<utility>
#include<string>
#include<string.h>
#include<vector>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
int cas,m,n;
char mp[101][101];
bool vis[101][101];
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
bool ck(int i,int j)
{
    if(i<1||i>n||j<1||j>m)return false;
    return true;
}
void dfs(int i,int j)
{
    vis[i][j]=true;
    int ti,tj;
    for(int t=0;t<4;t++){
        ti=i+dx[t];tj=j+dy[t];
        //cout<<"t "<<ti<<' '<<tj<<endl;//
        if(ck(ti,tj)&&mp[ti][tj]=='#'&&!vis[ti][tj])
            dfs(ti,tj);
    }
}
int main()
{
    std::ios::sync_with_stdio(false);
    cin>>cas;
    while(cas--){
        cin>>n>>m;
        int ans=0;
        memset(vis,false,sizeof(vis));
        FOR(i,1,n)FOR(j,1,m)cin>>mp[i][j];
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(!vis[i][j]&&mp[i][j]=='#'){
                    ans++;
                    dfs(i,j);
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

 

1005(hdu4432Sum of divisors)

src:http://acm.hdu.edu.cn/showproblem.php?pid=4432

注意n==1的时候不要加多了~~~

#include <iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<functional>
#include<utility>
#include<string>
#include<string.h>
#include<vector>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
int n,base;
int v[10000],cnt;
class baba
{
public:
    int b[100];
    int ct;
    baba(){memset(b,0,sizeof(b));ct=1;}
    void init(){memset(b,0,sizeof(b));ct=1;}
}tmp;
void dec_to_base(int u)
{
    while(u){
        tmp.b[tmp.ct++]=u%base;
        u/=base;
    }
}
int main()
{
    std::ios::sync_with_stdio(false);
    while(cin>>n>>base&&n&&base){
        cnt=2;v[1]=1;
        int ans=0;
        for(int i=2;i<sqrt(n);i++){
            if(n%i==0)v[cnt++]=i;
        }
        if(n!=1){
            int tt=cnt;
            for(int i=1;i<tt;i++)v[cnt++]=n/v[i];
            int ha=sqrt(n);
            if(ha*ha==n)v[cnt++]=ha;
        }
        for(int i=1;i<cnt;i++){
            tmp.init();
            dec_to_base(v[i]);
            for(int j=1;j<tmp.ct;j++){
                ans+=tmp.b[j]*tmp.b[j];
            }
        }

        tmp.init();
        dec_to_base(ans);
        for(int i=tmp.ct-1;i>=1;i--){
            if(tmp.b[i]>9)cout<<(char)('A'+(tmp.b[i]-10));
            else cout<<tmp.b[i];
        }
        cout<<endl;
    }
    return 0;
}
View Code

1006(hdu5984 Pocky)

src : http://acm.hdu.edu.cn/showproblem.php?pid=5984

题解:https://www.cnblogs.com/cmmdc/p/7747760.html

 

1007(hdu5978To begin or not to begin)src http://acm.hdu.edu.cn/showproblem.php?pid=5978

水水的概率题

#include <iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<functional>
#include<utility>
#include<string>
#include<string.h>
#include<vector>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
int n,half,sum,ans,ad;
int v[55],num[55],dp[2500000];


int main()
{
    int n;
    while(cin>>n){
        n++;
        if(n%2==1)cout<<"1"<<endl;
        else cout<<"0"<<endl;
    }
    return 0;
}
View Code

1008(hdu6247 这题贴的网上写的最简洁的代码~~~)

src:http://acm.hdu.edu.cn/showproblem.php?pid=6247

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int T,ca=0;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        int s=0;
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            s+=x+x/10+(x%10!=0);
        }
        printf("Case #%d: %d\n",++ca,s);
    }
    return 0;
}
View Code

1009(hdu6188Duizi and Shunzi)

src:http://acm.hdu.edu.cn/showproblem.php?pid=6188

贪心,优先考虑对子,然后顺子;

对于某个对子,假设能用来组成顺子,则是aab(b)c(c)形式(a在前中后都行),1️⃣如果bc的数量都是2则abc凑对子有三个,凑顺子2个,此时凑对子好;2️⃣如果bc不是都有两个,则凑成的对子和顺子一样多;所以对于a,先凑对子肯定不亏;然后如果还有剩下来,则称剩下来的为“弃子”,把它尽可能用掉就好,此时分析下一个,如果下一个也有这种弃子,则下下个直接拿来凑成顺子,因为就算下下个能组成对子,拿来消耗掉前两个弃子也不亏,反之如果下下个也有弃子就赚了呦~~~完结!!!

ac代码:

#include <iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<functional>
#include<utility>
#include<string>
#include<string.h>
#include<vector>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<=b;i++)

const int N=1000000+50;
int v[1000050],n,d;
int main()
{
    std::ios::sync_with_stdio(false);
    while(cin>>n){
        memset(v,0,sizeof(v));
        for(int i=1;i<=n;i++){
            cin>>d;
            v[d]++;
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            ans+=v[i]/2;
            v[i]%=2;
            if(v[i]&&v[i+1]%2&&v[i+2]){
                ans++;
                v[i]--;v[i+1]--;v[i+2]--;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

1010 (hdu3249Selecting Frames)

src:http://acm.hdu.edu.cn/showproblem.php?pid=3249

题意:给你N个线段,每个线段有一个自己pole,要选择尽量多的线段。

如果dp解的话,状态转移方程:dp[top]=min( dp[top] , a[i].p>=dp[top-1]+a[i].l?a[i].p:dp[top-1]+a[i].l); 可以看出,当前状态的最优解是由上一状态的最优解得来的,因此退成贪心解即可!!!

 

ac代码:

#include <iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<functional>
#include<utility>
#include<string>
#include<string.h>
#include<vector>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
int Max(int a,int b){return a>b?a:b;}
const int inf=9999999;
struct frame
{
    int len,p;
}fm[100005];
int n,old,nw;//old表示前一个最小右界,nw表示新的最小右界
bool cmp(frame f1,frame f2)
{
    if(f1.p==f2.p)return f1.len<f2.len;
    return f1.p<f2.p;
}

int main()
{
    std::ios::sync_with_stdio(false);
    while(cin>>n&&n){
        FOR(i,1,n)cin>>fm[i].len>>fm[i].p;
        sort(fm+1,fm+1+n,cmp);
        int sum=1;
        old=fm[1].p;nw=fm[1].p;
        for(int i=2;i<=n;i++){
            if(fm[i].p>=nw){
                sum++;
                old=nw;
                nw=Max(fm[i].p,old+fm[i].len);
                continue;
            }
            int tmp=max(fm[i].p,old+fm[i].len);
            if(tmp<nw)nw=tmp;
        }
        cout<<sum<<endl;
    }
    return 0;
}
View Code

 

posted @ 2018-04-15 23:08  WindFreedom  阅读(151)  评论(0)    收藏  举报