zoukankan      html  css  js  c++  java
  • 2017/10/20模拟赛

    面包人(van
    【题目描述】
    W 为了对抗小 C 的骑士阵, 叫来了一车面包人来攻打他。由
    于小 W 的后台很硬,他叫来的这一车总共有 n 个面包人,从 1~n
    号。但小 C 很快就摸清了这车面包人的实力,他发现他们的实力跟
    他们的编号以及编号的因数个数有着千丝万缕的关系。 假设τ (x)x
    的因数个数,如果对于编号为 x 的面包人,满足任意编号比他小的面
    包人 y, 都有τ (y)<τ (x),那么编号为 x 的面包人的实力就强于所有
    编号比他小的面包人,否则他的实力就弱于所有编号比他小的面包
    人。现在小 C 希望知道最强的和最弱的面包人的编号。
    【输入数据】
    输入只有一行, 一个正整数 n,表示面包人的个数。
    【输出数据】
    输出只有一行, 两个正整数,分别表示最强的和最弱的面包人编
    号,两个数之间用空格隔开。
    【样例输入】
    10
    【样例输出】
    6 10
    【数据范围】
    对于 8%的数据, n<=10
    对于 32%的数据, n<=10^5
    另外 8%的数据, n 为质数;
    对于 100%的数据, 1<=n<=2*10^9
    【样例解释】
    1~10 的因数个数分别是 1,2,2,3,2,4,2,4,3,4
    所以实力排序从弱到强为: 10<9<8<7<5<3<1<2<4<6

    PS:若 x=A^a+B^b+…+N^n.(A、B…均为质数)

        那么x的因数个数为 (a+1)*(b+1)*…*(n+1)

    题解:首先,我们发现,因数最多的数一定是若干质数的积,且数据范围内所用到的质数很少,那么,我们暴力dfs枚举所用的因数即可。

    代码如下:

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 int n,pr[10]={2,3,5,7,11,13,17,19,23,29},maxs,ans;
     5 void dfs(long long x,int cnt,int num){
     6     if(maxs<cnt) maxs=cnt,ans=x;
     7     if(maxs==cnt&&x<ans) ans=x;
     8     if(maxs>cnt&&x>ans) return;
     9     int sum=0;
    10     while(x*pr[num]<=n){
    11         x*=pr[num];
    12         sum++;
    13         dfs(x,cnt*(sum+1),num+1);
    14     }
    15 }
    16 int main()
    17 {
    18     freopen("van.in","r",stdin);
    19     freopen("van.out","w",stdout);
    20     scanf("%d",&n);
    21     if(n==1){printf("1 1");return 0;}
    22     dfs(1,1,0);
    23     printf("%d %d",ans,ans==n?n-1:n);
    24     return 0;
    25 }

    寻呼机(pager
    【题目描述】
    H 和小 S 现在都居住在 B 城, B 城地图可以看做是一个 n*n
    的网格图,小 H 住在(1,1),小 S 住在(n,n)B 城的通讯设施十分发达,
    每一个格子中都建有一座类型为 cij 的通讯塔。 位于(i,j)的通讯塔对于
    消息进行处理后只能将消息传输给位于(i+1,j)(i,j+1)的通讯塔。 一
    天,小 H 通过传呼机给小 S 发了一道长度为 n-1 的消息。 所以消息依
    次会经历 n-1 道加密、 1 道中枢处理和 n-1 道解密, 每个格子负责 1
    道处理,所以一共会经过 2n-1 个格子;根据加密解密原则,每一次
    解密会解开最后一次未被解密的加密,且该解密类型必须和对应的那
    一次加密类型相同,具体表现为对应的两个格子类型 cij 相同。满足
    以上条件能把信息成功从(1,1)传输到(n,n)的路径,称为合法信息通
    路。等待回复的时间很漫长,小 H 端详着 B 城地图,他希望知道不
    同的合法信息通路有多少种。
    【输入数据】
    第一行一个正整数 n, 表示 B 城大小。
    接下来 n 行,每行 n 个整数,表示 B 城每个格子的类型 cij
    【输出数据】
    输出一个整数,表示合法信息通路的种数, 答案对 10^9+7 取模。
    【样例输入】
    3
    1 2 3
    1 1 2
    2 1 1
    【样例输出】
    4
    【数据范围】
    对于 10%的数据, n<=10
    对于 30%的数据, n<=50
    对于 50%的数据, n<=100
    另外 5%的数据,所有的 cij均相等;
    另外 10%的数据, 0<=cij<=1
    对于 100%的数据, 1<=n<=5000<=cij<=10^9
    【样例解释】
    4 条路径:
    ① (1,1)-(1,2)-(1,3)-(2,3)-(3,3): 12321;
    ② (1,1)-(1,2)-(2,2)-(2,3)-(3,3): 12121;
    ③ (1,1)-(2,1)-(2,2)-(3,2)-(3,3): 11111;
    ④ (1,1)-(2,1)-(3,1)-(3,2)-(3,3): 11211。

    题解:因为xy特征值相加相同的数必在同一斜行,n^3 dp即可,内存不够所以用滚动数组。

    变量声明:f[i][j][k](i从0开始)表示第i斜行第j行的数到第n-2-i斜行第k行的数的方案数。

    状态转移方程:f[i][j][k]=f[i-1][j][k]+f[i-1][j-1][k]+f[i-1][j][k+1]+f[i-1][j-1][k+1]

    代码如下:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define ljm 1000000007
     5 using namespace std;
     6 int n,s[505][505],I=1;
     7 long long f[2][505][505],ans;
     8 int main()
     9 {
    10     freopen("pager.in","r",stdin);
    11     freopen("pager.out","w",stdout);
    12     scanf("%d",&n);
    13     for(int i=1;i<=n;i++)
    14         for(int j=1;j<=n;j++) scanf("%d",&s[i][j]);
    15     if(s[1][1]!=s[n][n]){printf("0");return 0;}
    16     f[0][1][n]=1;
    17     for(int i=1;i<=n-1;i++){
    18         memset(f[I],0,sizeof(f[I]));
    19         for(int j=1;j<=i+1;j++)
    20             for(int k=n-i;k<=n;k++){
    21                 int p1=i+2-j,p2=2*n-i-k;
    22                 if(s[j][p1]==s[k][p2])
    23                     f[I][j][k]=(f[I^1][j-1][k]+f[I^1][j][k+1]+f[I^1][j-1][k+1]+f[I^1][j][k])%ljm;
    24             }
    25         I^=1;
    26     }I^=1;
    27     for(int i=1;i<=n;i++) ans=(ans+f[I][i][i])%ljm;
    28     printf("%lld",ans%ljm);
    29     return 0;
    30 }

    疏散(nuclear)
    【题目描述】
    没有什么是一颗核弹解决不了的,如果有,那就来两颗。
    你的营地现在正在接受小 C 的核弹轰炸,心灵控制仪矿场啥的估
    计都要没了。你现在需要紧急疏散你各个建筑物里的部队,你的营地
    里共有 n 个建筑,疏散第 i 个建筑里的部队需要 ti 的时间, 在同一时
    刻内,你只能疏散一个建筑内的部队。然而你已经通过侦查部队知道
    了小 C 对于你的营地的轰炸方案,你的第 i个建筑会在 si时刻被炸毁,
    如果一个建筑里的部队正在疏散或还未疏散时建筑被炸毁,那么这个
    建筑里的部队就不能算被成功疏散,为了能够再积蓄兵力与小 C 一
    战,你希望疏散尽量多的建筑里的部队。
    【输入数据】
    第一行一个正整数 n,表示建筑个数。
    接下来 n 行,每行两个整数, ti 和 si。含义如题中所述。
    【输出数据】
    输出只有一行,表示最多能疏散多少建筑里的部队。
    【样例输入】
    3
    1 1
    10 101
    100 101

    【样例输出】
    2
    【数据范围】
    对于 10%的数据, n<=10;
    对于 20%的数据, n,ti,si<=2000;
    对于 50%的数据, n,ti,si<=20000
    另外 10%的数据,满足所有 si都相等。
    另外 20%的数据,满足所有 ti都相等。
    对于 100%的数据, 1<=n<=300000, 0<=si,ti<=10^9。
    【样例解释】
    先疏散第 1个建筑, 再疏散第 2或第 3 个建筑。

    据, n<=10;对于 20%的数据, n,ti,si<=2000;对于 50%的数据, n,ti,si<=20000另外 10%的数据,满足所有 si都相等。另外 20%的数据,满足所有 ti都相等。对于 100%的数据, 1<=n<=300000, 0<=si,ti<=10^9。【样例解释】先疏散第 1个建筑, 再疏散第 2或第 3 个建筑。

     题解:首先考虑贪心,我们把建筑按摧毁时间从小到大排序,若能疏散就疏散,若无法疏散就与已疏散的建筑所花时间最多的作比较,若小则替换,我们可以用堆维护这个最大值。

    代码如下:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<queue>
     5 #define MN 300005
     6 using namespace std;
     7 int n,ans; long long sum;
     8 struct node{int t,s;}a[MN];
     9 priority_queue<int> pq;
    10 bool cmp(node x,node y){return x.s<y.s;}
    11 int main()
    12 {
    13     freopen("nuclear.in","r",stdin);
    14     freopen("nuclear.out","w",stdout);
    15     scanf("%d",&n);
    16     for(int i=1;i<=n;i++) scanf("%d%d",&a[i].t,&a[i].s);
    17     sort(a+1,a+1+n,cmp);
    18     for(int i=1;i<=n;i++){
    19         if(sum+a[i].t<=a[i].s) ans++,sum+=a[i].t,pq.push(a[i].t);
    20         else if(!pq.empty()&&a[i].t<pq.top()){
    21             sum+=a[i].t-pq.top();
    22             pq.pop(); pq.push(a[i].t);
    23         }
    24     }
    25     printf("%d",ans);
    26     return 0;
    27 }
  • 相关阅读:
    阿里笔试题—战报交流
    2 基于梯度的攻击——PGD
    1 基于梯度的攻击——FGSM
    0 对抗样本
    自然语言处理 复习笔记 3
    自然语言处理 复习笔记 2
    自然语言处理 复习笔记 1
    GRU
    1*1卷积核的作用
    BP原理
  • 原文地址:https://www.cnblogs.com/Beginner-/p/7723195.html
Copyright © 2011-2022 走看看