zoukankan      html  css  js  c++  java
  • 开学第二测

                    开学第二测(好像是qbxt zhx出的题)

                              P69

    题目名称  

    希望  党
    名称    kami na wosa
    输入  kami.in   na.in wosa.in
    输出  kami.out na.out  wosa.out
    每个测试点时限 1 秒 1 秒 1 秒
    内存限制 512MB 512MB 512MB
    测试点数目  10 10 10
    每个测试点分值  10 10 10
    是否有部分分
    题目类型 传统 传统 传统

              注意 事项(请务必仔细阅读):

                                 

                     T1

                            希望
    【题目描述】
        网页浏览器者有后退与前进按钮,一种实现这两个功能的方式是用两个栈,“前进栈”、“后退栈”。
    这里你需要实现以下几个功能:

          BACK: 如果“后退栈”为空则忽略此命令。 否则将当前两面压入“前进栈”,从“后退栈”中取出栈顶页面,并设置为当前页面。
          FORWARD: 如果“前进栈”为空则忽略此命令。否则将当前两面压入“后退栈”,从“前进栈”中取出栈顶页面,并设置为当前页面。
          VISIT: 将当前页面压入“后退栈”、 并将当前页面置为指定页面, 并将“前进栈”置空。
          QUIT: 退出。
        假设此浏览器初始页面为 http://www.acm.org/
    【输入格式】
        输入为一系列命令:BACK, FORWARD, VISIT 和 QUIT,页面网址为不含空格的字符串
        假设任一时刻任意时刻两个栈中的元素都不会超过 100。
        最后一个命令为 QUIT。
    【输出格式】
        输对于除 QUIT 外所有命令,输出当前页面(网址)
        如果该命令被忽略则输出“Ignored”。
    【样例输入】
    VISIT http://acm.ashland.edu/
    VISIT http://acm.baylor.edu/acmicpc/
    BACK
    BACK
    BACK
    FORWARD
    VISIT http://www.ibm.com/
    BACK
    BACK
    FORWARD
    FORWARD
    FORWARD
    QUIT
    【样例输出】
    http://acm.ashland.edu/
    http://acm.baylor.edu/acmicpc/
    http://acm.ashland.edu/
    http://www.acm.org/
    Ignored
    http://acm.ashland.edu/
    http://www.ibm.com/
    http://acm.ashland.edu/
    http://www.acm.org/
    http://acm.ashland.edu/
    http://www.ibm.com/
    Ignored
    【数据范围与规定】
    对于100%的数据,操作数量不超过1000,每行字符串长度不超过500。

    思路:模拟

    #include<map>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 1010
    using namespace std;
    char s[101],ss[1001];
    int top1,top2,num,now;
    int stack1[MAXN],stack2[MAXN];
    map<int,string>ma;
    map<string,int>mm;
    int main(){
        //freopen("lppin.txt","r",stdin);
        freopen("kami.in","r",stdin);
        freopen("kami.out","w",stdout);
        ma[++num]="http://www.acm.org/";
        mm["http://www.acm.org/"]=num;
        now=1;
        while(cin>>s&&s[0]!='Q'){
            if(s[0]=='V'){
                cin>>ss;
                if(!mm[ss]){
                    ma[++num]=ss;
                    mm[ss]=num;
                }
                top1++;stack1[top1]=now;
                now=mm[ss];
                cout<<ss<<endl;top2=0;
            }
            else if(s[0]=='B'){
                if(top1){
                    top2++;stack2[top2]=now;
                    now=stack1[top1];top1--;
                    cout<<ma[now]<<endl;
                }    
                else cout<<"Ignored"<<endl;
            }
            else if(s[0]=='F'){
                if(top2){
                    top1++;stack1[top1]=now;
                    now=stack2[top2];top2--;
                    cout<<ma[now]<<endl;
                }
                else cout<<"Ignored"<<endl;
            }
        }
    }
    标程(这个应该不需要题解吧。。)

       T2  

                    残
    【问题描述】
        令f(n)为斐波那契数列第n项,其中f(0) = f(1) = 1,f(n) = f(n −1) +f(n −2)。
        所以要干啥呢?
        求f(f(n))。
    【输入格式】
        第一行一个整数T代表数据组数。
        接下来T行每行一个整数n。
    【输出格式】
        T行每行一个整数代表答案对10 9 + 7取模的值。
    【样例输入】
    4
    0
    1
    2
    6
    【样例输出】
    0
    1
    1
    21

    【数据规模与约定】
    对于20%的数据,1 ≤ n ≤ 15 。

    对于40%的数据,1 ≤ n ≤ 90。 
    对于70%的数据,1 ≤ n ≤ 105
    对于100%的数据,1 ≤ n ≤ 10 3 ,1 ≤ n ≤ 10 100 

    思路:矩阵快速幂 吧  (由于本人不会这个,所以用了记忆化搜索)

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define MOD 1000000007
    using namespace std;
    int t, n;
    long long f[10000005];
    
    long long dfs(int x) {
        if(x == 0) return f[x];
        if(f[x] != 0) return f[x];
        f[x] = dfs(x-1)%MOD + dfs(x-2)%MOD;
    }
    
    int main() {
    //    freopen("na.in","r",stdin);
    //    freopen("na.out","w",stdout);
        scanf("%d", &t);
        f[0] = 0; f[1] = f[2] = 1;
        for(int i = 1; i <= t; i++) {
            scanf("%d", &n);
            long long m = dfs(n)%MOD;
            long long ans = dfs(m) %MOD;
            printf("%lld
    ", ans);
        }
    //    fclose(stdin); fclose(stdout);
        return 0;
    }
    20分记忆化搜索
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define mod 1000000007
    using namespace std;
    typedef long long LL;
    int T, n;
    LL t[2][2], ans[2][2], r[2][2];
    void mul(LL a[2][2], LL b[2][2]) {
        memset(r, 0, sizeof(r));
        for(int i = 0; i < 2; i++)
            for(int j = 0; j < 2; j++)
                for(int k = 0; k < 2; k++)
                    r[i][j] += a[i][k]*b[k][j], r[i][j] %= mod;
        for(int i = 0; i < 2; i++)
            for(int j = 0; j < 2; j++)
                a[i][j] = r[i][j];
    }
    void mul1(LL a[2][2], LL b[2][2]) {
        memset(r, 0, sizeof(r));
        for(int i = 0; i < 2; i++)
            for(int j = 0; j < 2; j++)
                for(int k = 0; k < 2; k++)
                    r[i][j] += a[i][k]*b[k][j];
        for(int i = 0; i < 2; i++)
            for(int j = 0; j < 2; j++)
                a[i][j] = r[i][j];
    }
    int main() {
        //freopen("lppin.txt","r",stdin);
        //freopen("na.in","r",stdin);
        //freopen("na.out","w",stdout);
        scanf("%d", &T);
        while(T--) {
            scanf("%d", &n);
            memset(ans, 0, sizeof(ans));
            memset(t, 0, sizeof(t));
            if(n == 0) { cout << "0" << endl; continue; }
            t[0][0] = t[0][1] = t[1][0] = 1;
            ans[0][0] = ans[0][1] = 1;
            long long p;
            if(n==1 || n==2) p = 1;
            else {
                n -= 2;
                while(n) {
                    if(n & 1) mul1(ans, t);
                    mul1(t, t); n >>= 1;
                }
            } 
            p = ans[0][0];
            memset(ans, 0, sizeof(ans));
            memset(t, 0, sizeof(t));
            t[0][0] = t[0][1] = t[1][0] = 1;
            ans[0][0] = ans[0][1] = 1;
            if(p==1 || p==2){ cout << "1" << endl; continue; }
            else {
                p -= 2;
                while(p) {
                    if(p & 1) mul(ans, t);
                    mul(t, t); p >>= 1;
                }
            }
            cout << ans[0][0] << endl;
        }
    }
    学姐的40分快速幂暴力
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    
    using namespace std;
    
    #ifdef unix
    #define LL "%lld"
    #else
    #define LL "%I64d"
    #endif
    
    const int maxn=200;
    const long long mo=1000000007;
    const long long mo2=mo*2+2;
    const long long mo3=mo2*3;
    
    char s[maxn];
    
    struct matrix
    {
        long long z[3][3];
        matrix()
        {
            memset(z,0,sizeof(z));
        }
        matrix operator*(const matrix &a)const
        {
            matrix ans;
            for (int b=1;b<=2;b++)
                for (int c=1;c<=2;c++)
                    for (int d=1;d<=2;d++)
                        ans.z[b][c]=(ans.z[b][c]+z[b][d]*a.z[d][c]%mo)%mo;
            return ans;
        }
        matrix operator+(const matrix &a)const
        {
            matrix ans;
            for (int b=1;b<=2;b++)
                for (int c=1;c<=2;c++)
                    for (int d=1;d<=2;d++)
                        ans.z[b][c]=(ans.z[b][c]+z[b][d]*a.z[d][c]%mo2)%mo2;
            return ans;
        }
    }m1,m2;
    
    struct bign
    {
        int z[maxn],l;
        void init()
        {
            memset(z,0,sizeof(z));
            scanf("%s",s+1);
            l=strlen(s+1);
            for (int a=1;a<=l;a++)
                z[a]=s[l-a+1]-'0';
        }
        long long operator%(const long long &a)const
        {
            long long b=0;
            for (int c=l;c>=1;c--)
                b=(b*10+z[c])%a;
            return b;
        }
    }z;
    
    long long get(long long v)
    {
        if (v==0) return 0;
        m1.z[1][1]=0;
        m1.z[1][2]=1;
        m2.z[1][1]=0;
        m2.z[1][2]=m2.z[2][1]=m2.z[2][2]=1;
        while (v)
        {
            if (v&1) m1=m1*m2;
            m2=m2*m2;
            v>>=1;
        }
        return m1.z[1][1];
    }
    
    long long get1(long long v)
    {
        if (v==0) return 0;
        m1.z[1][1]=0;
        m1.z[1][2]=1;
        m2.z[1][1]=0;
        m2.z[1][2]=m2.z[2][1]=m2.z[2][2]=1;
        while (v)
        {
            if (v&1) m1=m1+m2;
            m2=m2+m2;
            v>>=1;
        }
        return m1.z[1][1];
    }
    
    int main()
    {
        freopen("na.in","r",stdin);
        freopen("na.out","w",stdout);
    
        int t;
        scanf("%d",&t);
        for (int a=1;a<=t;a++)
        {
            z.init();
            long long v1=z % mo3;
            v1=get1(v1);
            printf(LL "
    ",get(v1));
        }
    
        return 0;
    }
    标程 学姐也没看懂,我就不奢求了。。

            T3

                   党

    【问题描述】
        你现在希望组建一支足球队,一支足球队一般来说由11人组成。这11人有四种不同的职业:守门员、后卫、中锋、前锋组成。你在组队的时候必须满足以下
        规则:
          1、 足球队恰好由11人组成。
          2、 11人中恰好有一名守门员,3-5 名后卫,2-5 名中锋,1-3 名前锋。
          3、 你需要从这11人中选出一名队长。
          4、 你这个足球队的价值是11人的价值之和再加上队长的价值, 也就是说队长的价值会被计算两次。
          5、 你这个足球队的花费是11人的花费之和, 你的花费之和不能超过给定的上限。
        现在告诉你球员的总数,每个球员的职业、价值、花费,以及花费的上限,你希望在满足要求的情况下,达到以下目标:
          1、 最大化队伍的价值。
          2、 在最大化队伍的价值的情况下,最小化队伍的花费。
          3、 在满足以上两个要求的情况下,有多少种选择球员的方案。如果有两种方案它们的区别仅仅是队长不一样, 那么这两种方案应该被认为是一种方案。
        你的任务是输出这三个值:价值、花费、方案数。
    【输入格式】
        第一行一个正整数N,代表可选的球员个数。
        接下来N行,每行描述一个球员的信息。每行开始是一个字符串,可能的字符串有 Goalkeeper、Defender、Midfielder、Forward,分别代表该球员的职业是守门员、后卫、中锋、前锋。接下来两个数V,C,分别代表该球员的价值和花费。
        最后一行一个整数,代表花费的上限。
        数据保证一定存在一种解。
    【输出格式】
        一行三个整数,分表代表最大价值、最小花费和方案数。如果方案数超过了10 9 ,则直接输出10 9

    思路:动规(DP),好像是背包(题解说的),不过具体是什么背包我就不知道了╮(╯▽╰)╭

    #include<map>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 510
    using namespace std;
    map<string,int>ma;
    int vis[MAXN];
    int n,H,mmp,ansval=-1,anscost=0x7f7f7f7f,ans;
    struct nond{
        int job,val,cost;
    }v[MAXN];
    void dfs(int now,int sum,int val,int cost,int door,int back,int mid,int front,int head){
        if(sum+n-now+1<11)    return ;
        if(cost>H)    return ;
        if(sum==11&&door!=0&&back>=3&&back<=5&&mid>=2&&mid<=5&&front>=1&&front<=3&&head!=0){
            string s;
            for(int i=1;i<=n;i++)    s+=char(vis[i]+'0');
            s+=char(head+'0');
            if(val>ansval){
                ansval=val;anscost=cost;
                ans=1;ma[s]=1;
            }
            else if(val==ansval){
                if(anscost==cost){
                    if(!ma[s]){
                        if(val==716&&ans==1){
                            int hh=1;
                        }
                        ma[s]=1;ans++;
                    }
                }
                else if(cost<anscost){ anscost=cost; ans=1; }
            }
            return ;
        }
        if(now>n)    return ;
        if(v[now].job==1){
            if(door==0)    vis[now]=1,dfs(now+1,sum+1,val+v[now].val,cost+v[now].cost,1,back,mid,front,head),vis[now]=0;
            if(door==0&&head==0)    vis[now]=1,dfs(now+1,sum+1,val+v[now].val*2,cost+v[now].cost,1,back,mid,front,now),vis[now]=0;
            dfs(now+1,sum,val,cost,door,back,mid,front,head);    
        }
        else if(v[now].job==2){
            if(back<5)    vis[now]=1,dfs(now+1,sum+1,val+v[now].val,cost+v[now].cost,door,back+1,mid,front,head),vis[now]=0;
            if(back<5&&head==0)    vis[now]=1,dfs(now+1,sum+1,val+v[now].val*2,cost+v[now].cost,door,back+1,mid,front,now),vis[now]=0;
            dfs(now+1,sum,val,cost,door,back,mid,front,head);
        }
        else if(v[now].job==3){
            if(mid<5)    vis[now]=1,dfs(now+1,sum+1,val+v[now].val,cost+v[now].cost,door,back,mid+1,front,head),vis[now]=0;
            if(mid<5&&head==0)    vis[now]=1,dfs(now+1,sum+1,val+v[now].val*2,cost+v[now].cost,door,back,mid+1,front,now),vis[now]=0;
            dfs(now+1,sum,val,cost,door,back,mid,front,head);
        }
        else if(v[now].job==4){
            if(front<3)    vis[now]=1,dfs(now+1,sum+1,val+v[now].val,cost+v[now].cost,door,back,mid,front+1,head),vis[now]=0;
            if(front<3&&head==0)    vis[now]=1,dfs(now+1,sum+1,val+v[now].val*2,cost+v[now].cost,door,back,mid,front+1,now),vis[now]=0;
            dfs(now+1,sum,val,cost,door,back,mid,front,head);
        }
    }
    int cmp(nond a,nond b){
        if(a.val==b.val)    return a.cost<b.cost;
        return a.val>b.val;
    }
    int main(){
        //freopen("lppin.txt","r",stdin);
        freopen("wosa1.in","r",stdin);
        freopen("wosa.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            char c[100];cin>>c;
            int y,z;cin>>y>>z;mmp+=z;
            if(c[0]=='G')    v[i].job=1;
            else if(c[0]=='D')    v[i].job=2;
            else if(c[0]=='M')    v[i].job=3;
            else if(c[0]=='F')    v[i].job=4;
            v[i].val=y;v[i].cost=z;
        }
        cin>>H;
        if(n<=20){
            dfs(1,0,0,0,0,0,0,0,0);
            cout<<ansval<<" "<<anscost<<" "<<ans;
        }
        else if(H>=mmp){
            sort(v+1,v+1+n,cmp);
            for(int a=3;a<=5;a++)
                for(int b=2;b<=5;b++){
                    int c=11-1-a-b;
                    int door=0,back=0,mid=0,front=0,val=0,cost=0;
                    if(c<1)    continue;
                    for(int i=1;i<=n;i++){
                        if(v[i].job==1){
                            if(door==0)    door=1,val+=v[i].val,cost+=v[i].cost;
                        }
                        else if(v[i].job==2){
                            if(back<a)    back++,val+=v[i].val,cost+=v[i].cost;
                        }
                        else if(v[i].job==3){
                            if(mid<b)    mid++,val+=v[i].val,cost+=v[i].cost;
                        }
                        else if(v[i].job==4){
                            if(front<c)    front++,val+=v[i].val,cost+=v[i].cost;
                        }
                    }
                    val+=v[1].val;
                    if(val>ansval){ ansval=val; ans=1; }
                    if(val==ansval){
                        if(cost==anscost)    ans++;
                        else if(cost<anscost){ anscost=cost;ans=1; }
                    }
                }
            if(ans>100)    ans=1000000000;
            cout<<ansval<<" "<<anscost<<" "<<ans;
        }
        else {
            dfs(1,0,0,0,0,0,0,0,0);
            cout<<ansval<<" "<<anscost<<" "<<ans;
        }
    }
    学姐的30分暴力
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define mod 1000000000
    using namespace std;
    struct nond{
        int job,val,cost;    
    }v[501];
    int n,H,ansval=-1,anscost,ans;
    int L[5],R[5];
    int f[2][6][6][4][1001][3];
    /*f[a][b][c][d][e][f]表示到花费了e元为至
     a表示选的守门员,b表示选了几个后卫,c表示选了几个中锋,
     e表示选了几个前锋
     f如果等于0表示价值,如果是1表示方案数,如果是2表示队长价值*/
    int cmp(nond a,nond b){
        if(a.val==b.val)    return a.cost>b.cost;
        return a.val<b.val;
    }
    void up(int a,int b,int c,int d,int e,int val,int num,int mx){
        if(f[a][b][c][d][e][0]<val){
            f[a][b][c][d][e][0]=val;
            f[a][b][c][d][e][1]=num;
            f[a][b][c][d][e][2]=mx;
        }
        else if(f[a][b][c][d][e][0]==val&&f[a][b][c][d][e][2]<mx){
            f[a][b][c][d][e][1]=num; 
            f[a][b][c][d][e][2]=mx;
        }
        else if(f[a][b][c][d][e][0]==val&&f[a][b][c][d][e][2]==mx){
            f[a][b][c][d][e][1]+=num;
            if(f[a][b][c][d][e][1]>mod)
                f[a][b][c][d][e][1]=mod;
        }
    }
    /*背包*/
    void insert(int x){
        for(int a=R[1]-(v[x].job==1);a>=0;a--)
            for(int b=R[2]-(v[x].job==2);b>=0;b--)
                for(int c=R[3]-(v[x].job==3);c>=0;c--)
                    for(int d=R[4]-(v[x].job==4);d>=0;d--)
                        for(int e=H-v[x].cost;e>=0;e--)
                            if(f[a][b][c][d][e][1]){
                                int val=v[x].val+f[a][b][c][d][e][0];
                                up(a+(v[x].job==1),b+(v[x].job==2),c+(v[x].job==3),d+(v[x].job==4),e+v[x].cost,val,f[a][b][c][d][e][1],v[x].val); 
                            }
    } 
    int main(){
        freopen("wosa4.in","r",stdin);
        //freopen("wosa.out","w",stdout);
        //freopen("1wosaout.txt","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            char s[100];cin>>s;
            int x,y;cin>>x>>y;
            if(s[0]=='G')    v[i].job=1;
            if(s[0]=='D')    v[i].job=2;
            if(s[0]=='M')    v[i].job=3;
            if(s[0]=='F')    v[i].job=4;
            v[i].val=x;v[i].cost=y;
        }
        scanf("%d",&H);
        L[1]=1;R[1]=1;L[2]=3;R[2]=5;
        L[3]=2;R[3]=5;L[4]=1;R[4]=3;
        //分别表示4种人所选的人数的限制范围。 
        sort(v+1,v+1+n,cmp);//预处理排序(不明白啊啊啊啊,为什么这么排) 
        f[0][0][0][0][0][1]=1;    //没选的方案数。 
        f[0][0][0][0][0][2]=-1;    //没选的队长价值(没有队长,所以设成-1) 
        for(int i=1;i<=n;i++)    insert(i);
        for(int a=L[1];a<=R[1];a++)
            for(int b=L[2];b<=R[2];b++)
                for(int c=L[3];c<=R[3];c++)
                    for(int d=L[4];d<=R[4];d++)
                        if(a+b+c+d==11)
                            for(int e=0;e<=H;e++){
                                if(f[a][b][c][d][e][1]==0)    continue;
                                int val=f[a][b][c][d][e][0]+f[a][b][c][d][e][2];
                                if(val>ansval){
                                    ansval=val;anscost=e;
                                    ans=f[a][b][c][d][e][1];
                                }
                                else if(val==ansval&&e<anscost){
                                    anscost=e;
                                    ans=f[a][b][c][d][e][1];
                                }
                                else if(val==ansval&&e==anscost){
                                    ans+=f[a][b][c][d][e][1];
                                    if(ans>mod)    ans=mod;
                                }
                            }
        cout<<ansval<<" "<<anscost<<" "<<ans;
    }
    标程(内带题解)
  • 相关阅读:
    浅析区间问题
    关于参加信息竞赛
    路爷爷语录
    CentOS-7安装python虚拟环境
    开发笔记(不定时更新)
    Redis有序集合的权重值选择
    数据缓存(Redis)流程设计--思路
    Flask框架之配置日志信息
    Flask框架之一对多关系模型定义
    Flask框架之多对多关系模型类的定义
  • 原文地址:https://www.cnblogs.com/v-vip/p/8645250.html
Copyright © 2011-2022 走看看