开学第二测

                开学第二测(好像是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\n", 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分快速幂暴力

标程 学姐都看不懂,我就不奢求了。。

        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;
}

标程(内带题解)

原文地址:https://www.cnblogs.com/v-vip/p/8645250.html

时间: 2024-10-07 14:12:20

开学第二测的相关文章

开学第二天

开学第二天,感觉比第一天收获更大,过的更加充实,主要是因为接触更多的陌生知识吧,感觉计算机语言最重要的是积累,再就是变通和练习. 一. 1.class Program(项目类) 2.static void Main(string[] args)(主函数,函数的入口,一个项目只有一个) 3.Console.WriteLine("Hello World!");        //输出(打印)//打印完成之后,进行换行 4.console.readline()方法获取到的是string类型,

18寒假第二测

第一题:二维树状数组,bit[x][y]表示从(1,1)到(x,y)的和,二维的坐标从一维的推过来,正确性可以用一个递增和一个递减的序列单调性证明,至于构图就当黑箱吧 #include <cstdio> int n, m, q; struct Case1 { int bit[100010]; void modify( int p, int d ) { for( int i = p; i <= m; i += i & -i ) bit[i] += d; } int query( i

5.31联合第二测

this  is  a  sad  thing //本文置顶,希望不要再有contest的总结和它争位置 淋了点雨,头有点疼,中午罚自己没吃饭, 他说要化悲愤为食欲,可是我就是吃不下去. 还记得以前的时候,为了节约时间,一起跑去超市买个面包,然后再跑回来的事,结果两个人时间没节约多少,反而都病了,于是就要喝药. TA现在很优秀... 喜欢那时候的自己,可能有很多不好,很多人不理解,但是,嗯,就这样. 老王发现的一个bug T1Analyse:暴力能过的题... 其实灰常灰常的简单,不过... 1

暑假第二测

题解: 第一题: 如果A矩形的前缀和MOD K = P, C矩形的前缀和MOD K =P,说明中间的矩形MOD K= 0: 所以枚举列起点, 终点, 行数, 统计余数出现次数 O(n*M*M); #include <bits/stdc++.h> const int M = 405, N = 1e6 + 10; using namespace std; #define rt register int a[M][M], sum[M][M], vis[N], lie[M][M], ret[M]; i

BZOJ NOI十连测 第二测 T2

思路:20%可以搜索.. 1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 #include<time.h> 7 #define ll long long 8 const ll Mod=998244353; 9 ll jc[300005],jcny[300005]; 10 int n

开学第二天——2.26

今天上午是大物和程序设计. 大物竟然和经管的经济一起,上了一半课才意识到林雪慧也在里边,我俩是最不像老乡的老乡..哈哈..基本不认识..话说,经管学物理有啥用.. 经济不少漂亮妹子,听说赵总盯着他女神看了一节课,哈哈. 程序设计讲指针,好混乱.. 下午从3点到7点把上半年的那些截图图片之类的整理好了,把F盘又整理一遍,心情大好.晚上的ACM集训继续被虐.. 参加了FINA的面试志愿者,但愿能过,参加一下大型活动,不过会耽误课.. 晚上看了一个博客,鸡蛋不能放到一个篮子里.ACM学得好,那些公司面

开学第二周Java课堂测验暨简易出题代码

代码可以实现的功能包括实现两位数的四则运算,并同时保证乘法的结果不超过100,除法的结果为整数,减法的结果为正. 除此以外,用户还可以设置出题的数量,以及每一行的题目数目. 源码为:2901583663 package first; import java.util.Scanner;import java.util.Random;public class one {static Scanner sc = new Scanner(System.in); public static void mai

Servlet的乱码处理手记

前记 今天开学第二天,老师教了我们如何处理Servlet中的乱码.涵盖了所有乱码的处理. 1.处理post方法传入的乱码       -----修改servlet中的乱码              request.setCharacterEncoding("utf-8");             response.setCharacterEncoding("utf-8");       ----设置页面展示的编码            resp.setHeader

学习感悟2

开学第二天,继学习感悟1开始写学习感悟2 1.今天主要学习了面向对象的编程,Ecmascript主要包括两种属性,1是数据属性,2是访问器属性,其中数据属性有4个描述其行为的特性(configurable.enumerable.writable.value)访问器属性同样也包括4个属性(configurable.enumerable.get.set) 2.面型对象有很多设计模式 (1)工厂模式 function creatPerson(name,age,job){ var o = new Obj