• jxnu acm新生选拔赛


    最小的数

    Problem Description

    定义一种正整数集合K,集合中有N个数,集合中元素Ki(1<=i<=N)是包含i个不同质因子的最小的数。因为Ki可能会很大,所以将集合中所有Ki对10^9+7取余。

    Input

    本题只有唯一一组测试数据,第一行给出N,q,表示K的个数以及q次询问。1<=N<=1000,q<=10^5.
    接下来q行每行一个正整数(64位整数范围内),请判断其对10^9+7取余后,是否在集合K中。

    Output

    对于每次询问,根据题意输出Yes或No

    Sample Input

    3 3
    2
    6
    33
    

    Sample Output

    Yes
    Yes
    No

    直接用set保存下,查询就从set里查询就行。
     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #include <set>
     6 #define ll long long
     7 using namespace std;
     8 const int MAX = 1e4+10;
     9 const int MOD = 1e9+7;
    10 int vis[10010],b[MAX*10],k;
    11 void init() {
    12     for(int i = 2; i < 10000; i ++) {
    13         if(!vis[i]){
    14             b[++k] = i;
    15             for(int j = i+i; j < 10000; j += i)
    16                 vis[j] = 1;
    17         }
    18     }
    19 }
    20 int main() {
    21     int n,q;
    22     std::ios::sync_with_stdio(false);
    23     init();
    24     cin>>n>>q;
    25     set<ll> st;
    26     for(int i = 1; i <= n; i ++) {
    27         ll ans = 1;
    28         for(int j = 1; j <= i; j ++) {
    29             ans = 1LL*b[j]*ans%MOD;
    30         }
    31         st.insert(ans);
    32     }
    33     ll num;
    34     while(q--) {
    35         cin>>num;
    36         if(st.count(num)) printf("Yes
    ");
    37         else printf("No
    ");
    38     }
    39     return 0;
    40 }

    不安全字符串


    Problem Description

    集训十分无聊,于是boss发明了一个“益智”游戏——假设有一段仅由U和L构成的字符串,我们定义当连续的U的个数大于等于三的时候,这个字符串是不安全的。现告诉你字符串的长度n,请你算出能够生成多少个不安全字符串。

    Input

    输入有多组,每组仅输入一个n,代表字符串的长度,当n等于0的时候输入结束。(4<=n<=30)

    Output

    输出可生成的不安全字符串的个数。

    Sample Input

    4
    5
    0

    Sample Output

    3
    8
    
    Hint:对于第一个样例,当n为4的时候,我们满足条件的有 UUUU LUUU UUUL 三种情况

    思路:递推吧,因为每一个情况都是由前一个情况转变过来的,所以用一个dp数组去存每个情况相应的值,每一层的意思如下:(i为当前序列的长度)

    dp[i][0]没有三个连续U的序列最右边为L
    dp[i][1]没有三个连续U的序列最右边有一个U
    dp[i][2]没有三个连续U的序列最右边有两个连续的U
    dp[i][3]有三个连续的U的序列

    结合每个情况可以发现

      1. dp[i][0]可以由dp[i-1][0]+dp[i-1][1]+dp[i-1][2]转变过来,因为前一状态只要不是有了3个连续的U的序列,在最右边加一个L就可以形成
      2. dp[i][1]可以由dp[i - 1][0]转变过来,因为只能是在最右边没有U的序列加上个U形成
      3. dp[i][2]可以由dp[i - 1][1]转变过来,因为只能是在最右边有一个U的序列加上个U形成
      4. dp[i][3]可以由dp[i - 1][3] * 2 + dp[i - 1][2]转变过来,因为如果原本就是有连续3个U的序列最右边加上什么都是该情况,然后也可以在最右边有两个U的序列加上个U形成
    
    
     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #define ll long long
     5 using namespace std;
     6 ll dp[33][4];
     7 int main() {
     8     dp[1][0] = dp[1][1] = 1;
     9     dp[1][2] = dp[1][3] = 0;
    10     for(int i = 2; i < 33; i ++) {
    11         dp[i][0] = dp[i-1][0] + dp[i-1][1] + dp[i-1][2];
    12         dp[i][1] = dp[i-1][0];
    13         dp[i][2] = dp[i-1][1];
    14         dp[i][3] = dp[i-1][3]*2 + dp[i-1][2];
    15     }
    16     int n;
    17     while(scanf("%d",&n)&&n) {
    18         cout << dp[n][3] << endl;
    19     }
    20     return 0;
    21 }

    壮壮的数组


    Problem Description

    A,B,C为三个元素个数为n的数组,A={a1,a2,a3...an},B={b1,b2,b3...bn},C={c1,c2,c3...cn};
    已知A、B数组,而且有ci等于ai或bi(1<=i<=n),毫无疑问,C数组有很多种组合。
    但是zz不希望C数组全由A数组或者B数组组成,每一种组合都有一个K值,K=c1*c2*c3*...*cn。
    现在需要你求出每一种组合对应的K值,并将它们加起来的结果。这个结果可能会很大,请将答案对1e9+7取模。
    例如A={1,2,3} B={2,2,4}。
    C数组可能为{a1,b2,b3} {b1,a2,b3} {b1,b2,a3} {a1,a2,b3} {a1,b2,a3} {b1,a2,a3}
    K值分别为8,16,12,8,6,12,所以你应该输出62。

    大量输入,建议使用scanf

    Input

    输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(1<=n<=100000),表示A,B,C数组元素个数,第二行有n个数据表示a1 a2 a3...an,第三行有n个数据表示b1 b2 b3...bn,(1<=ai,bi<=1e9)。处理到文件的结束。

    Output

    对于每个测试实例,输出一行数据表示问题的答案,请将答案对1e9+7取模。

    Sample Input

    3
    1 2 3
    2 2 4
    1
    3
    4
    

    Sample Output

    62
    0
    

    其实就是求(a1+b1)*(a2+b2)*....*(an+bn)-a1*a2...*an-b1*b2*...*bn。答案取摸就行。
     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #define ll long long
     5 using namespace std;
     6 const int MAX = 100010;
     7 const int mod = 1e9+7;
     8 ll a[MAX], b[MAX];
     9 int main() {
    10     int n;
    11     std::ios::sync_with_stdio(false);
    12     while(cin>>n) {
    13         ll ans = 1;
    14         for(int i = 1; i <= n; i ++) {
    15             cin >> a[i];
    16             ans *= a[i];
    17             ans %= mod;
    18         }
    19         ll cnt = 1;
    20         for(int i = 1; i <= n; i ++) {
    21             cin >> b[i];
    22             cnt *= b[i];
    23             cnt %= mod;
    24         }
    25         ll sum = 1;
    26         for(int i = 1; i <= n; i ++) {
    27             sum *= (a[i]+b[i]);
    28             sum %= mod;
    29         }
    30         cout << (sum+mod-ans+mod-cnt)%mod << endl;
    31     }
    32     return 0;
    33 }

    涛涛的Party

    Problem Description

    涛神因为极强,并且特别帅,所以拥有很多美女的联系方式,每个美女都有自己的食量以及魅力值,大家都知道,物以类聚,人以群分,朋友的朋友就是自己的朋友,所以美女一般都是有自己的美女朋友圈,而且这些美女特别团结,如果她的朋友有没有被邀请的她就不会答应邀请。涛涛想办一个party,但是他只准备了w kg的食物,他想获得最大的美女魅力值,不知道怎么邀请美女,于是他去问你,你能告诉他,他能获得的美女魅力数是多少吗

    Input

    数据有多组,第一行输入n,m和w(1≤n≤1000,0≤m≤min(n*(n-1)/2,10^5),1≤w≤1000);第二行输入n个整型变量w1,w2,...,wn(1≤wi≤1000)代表美女i的食量;第三行输入n个整型变量b1,b2,...,bn(1≤bi≤106)代表美女i的魅力值;接下来的m行输入两个数x和y(1≤xi,yi≤n,xi≠yi),代表x和y是朋友

    Output

    输出涛涛能获得的最大魅力值

    Sample Input

    3 1 5
    3 2 5
    2 4 2
    1 2
    4 2 11
    2 4 6 6
    6 4 2 1
    1 2
    2 3
    

    Sample Output

    6
    1
    

    并查集和01背包的运用,同一个集合下的人可以当成一个人。
     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #include <set>
     6 using namespace std;
     7 int n,m,W;
     8 int w[1010], b[1010],fa[1010], dp[1010];
     9 struct Nod{
    10     int w, b;
    11     Nod(){
    12         w = b = 0;
    13     }
    14 }nod[1010];
    15 int find(int x) {
    16     return fa[x] = (x==fa[x])?x:find(fa[x]);
    17 }
    18 void unite(int x, int y) {
    19     x = find(x);
    20     y = find(y);
    21     if(x < y) fa[y] = x;
    22     else fa[x] = y;
    23 }
    24 int main() {
    25     std::ios::sync_with_stdio(false);
    26     while(cin>>n>>m>>W) {
    27         for(int i = 1; i <= n; i ++) cin>>w[i],fa[i] = i;
    28         for(int i = 1; i <= n; i ++) cin>>b[i];
    29         for(int i = 1; i <= m; i ++) {
    30             int x, y;
    31             cin>>x>>y;
    32             unite(x,y);
    33         }
    34         for(int i = 1; i <= n; i ++) {
    35             int x = find(i);
    36             nod[x].w += w[i];
    37             nod[x].b += b[i];
    38         }
    39         for(int i = 1; i <= n; i ++) {
    40             if(nod[i].b != 0 && nod[i].w != 0) {
    41                 for(int j = W; j >= nod[i].w; j --) {
    42                     dp[j] = max(dp[j],dp[j-nod[i].w]+nod[i].b);
    43                 }
    44             }
    45         }
    46         printf("%d
    ",dp[W]);
    47         for(int i = 1; i <= n; i ++){
    48             nod[i].b = nod[i].w = 0;
    49         }
    50         memset(dp,0,sizeof(dp));
    51     }
    52     return 0;
    53 }

    手机信号

    Problem Description

    现在在市面上流传了一款功能极简的手机,在手机上用一个 7×7 的显示屏来显示手机信号,每个区块能显示一个字符。满信号的时候显示如下:

    +-----+
    |- 4G|
    |-- |
    |--- |
    |---- |
    |-----|
    +-----+
    (杭电描述区块对字宽的设定不统一,正确显示请看输出样例)
    每一格信号(第i(1≤i≤5) 格信号有 i个-)代表 20% 的信号强度,不足一格信号的部分不显示。同时会在右上角显示当前的网络传输模式。在信号强度不低于 90% 的时候显示4G;当信号低于 90%、不低于 60% 的时候显示3G;否则显示E。
    对于给定的当前信号强度 d%,输出信号的 7×7 像素的图案。

    Input

    输入一个整数 d(0≤d≤100),表示信号强度。

    Output

    按照题目要求输出,每行末尾不要输出多余的空白字符。

    Sample Input

    0
    65
    

    Sample Output

    +-----+
    |    E|
    |     |
    |     |
    |     |
    |     |
    +-----+
    +-----+
    |-  3G|
    |--   |
    |---  |
    |     |
    |     |
    +-----+

    直接判断下就行了。
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int main(){
     4     int d;
     5     while(cin>>d){
     6         if(d < 20){
     7             cout << "+-----+
    |    E|
    |     |
    |     |
    |     |
    |     |
    +-----+
    ";
     8         }else if(d < 40){
     9             cout << "+-----+
    |-   E|
    |     |
    |     |
    |     |
    |     |
    +-----+
    ";
    10         }else if(d < 60){
    11             cout << "+-----+
    |-   E|
    |--   |
    |     |
    |     |
    |     |
    +-----+
    ";
    12         }else if(d < 80){
    13             cout << "+-----+
    |-  3G|
    |--   |
    |---  |
    |     |
    |     |
    +-----+
    ";
    14         }else if(d < 90){
    15             cout << "+-----+
    |-  3G|
    |--   |
    |---  |
    |---- |
    |     |
    +-----+
    ";
    16         }else if(d < 100){
    17             cout << "+-----+
    |-  4G|
    |--   |
    |---  |
    |---- |
    |     |
    +-----+
    ";
    18         }else if(d == 100){
    19             cout << "+-----+
    |-  4G|
    |--   |
    |---  |
    |---- |
    |-----|
    +-----+
    ";
    20         }
    21     }
    22     return 0;
    23 }

    涛神的城堡

    Problem Description

    涛神有一个城堡给游客参观,涛神特别的强壮,涛神的强壮值是strong,每个游客也有自己的强壮值,涛神为了赚钱,他会选取多个区间去打劫别人,所以如果比涛神弱的,他就要收取他们的强壮值的差值,但是还是有比涛涛强壮的,所以涛涛打劫那个人的话,涛涛要给那个人他们的强壮值的差值,所以涛涛可以选择打不打劫那个区间的人,(人是可以重复打劫的,区间不行)涛涛最多能赚多少钱呢?

    Input

    第一行给你三个整型变量n,m,strong(1≤n,m≤10000,1≤strong≤200),
    第二行给你n个人的强壮值a1,a2,...,an(1≤ai≤200).
    接下来m行给你两个整型变量l,r(1≤li≤ri≤n),代表区间里包括了第l个游客到第r个游客,涛涛可以选择打不打劫这个区间

    Output

    输出涛涛可以打劫到的最多的钱

    Sample Input

    5 4 10
    9 12 9 7 14
    1 2
    4 5
    3 4
    1 4
    

    Sample Output

    7
    这题有毒,题目说区间不行,但必须按可以取重复的区间才能AC。
     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #define ll long long
     5 using namespace std;
     6 const int MAX = 10010;
     7 ll sum[MAX], str;
     8 int main() {
     9     std::ios::sync_with_stdio(false);
    10     int n, m;
    11     while(cin>>n>>m>>str) {
    12         ll x;
    13         for(int i = 1; i <= n; i ++) {
    14             cin >> x;
    15             sum[i] = sum[i-1] + str - x;
    16         }
    17         ll ans = 0;
    18         while(m--) {
    19             int l, r;
    20             cin >> l >> r;
    21             ll y = sum[r] - sum[l-1];
    22             if(y > 0) ans += y;
    23         }
    24         cout << ans << endl;
    25         memset(sum,0,sizeof(sum));
    26     }
    27 }

    dada的GCD

    Problem Description

    C语言都学过了怎么计算两个数的最大公约数,而一段区间[L,R]的GCD即这段区间所有数的最大公约数。现在给你一串长度为n的序列,如果对于序列的任意子区间[L,R],都有这段区间的gcd>=2,那么这段序列就叫做dada的GCD序列。
    n<=10^4
    序列的每个数小于10^9

    Input

    第一行有一个整数t,代表t组数据
    每组输入有一个正整数n,
    随后一行n个正整数。

    大量输入,使用cin的同学请关闭stdio同步

    Output

    如果是dada的GCD序列,就输出Yes,反之输出No

    Sample Input

    2
    3
    2 6 4
    3
    4 6 9
    

    Sample Output

    Yes
    No
    语文水平有待提高了,竟然没看懂题意,写了几次都是靠猜的,赛后猜知道要全部的最大公约数大于等于2就行。
     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #define ll long long
     6 using namespace std;
     7 const int MAX = 1e5;
     8 ll a[MAX];
     9 ll gcd(ll a, ll b){
    10     return b?gcd(b,a%b):a;
    11 }
    12 int main() {
    13     std::ios::sync_with_stdio(false);
    14     int t, n;
    15     cin>>t;
    16     while(t--) {
    17         cin>>n;
    18         for(int i = 1; i <= n; i ++) {
    19             cin >> a[i];
    20         }
    21         if(n == 1){
    22             if(a[0] >= 2) puts("Yes");
    23             else puts("No");
    24         }else {
    25             ll ans = gcd(a[0],a[1]);
    26             for(int i = 2; i <= n; i ++) ans = gcd(ans,a[i]);
    27             if(ans >= 2)puts("Yes");
    28             else puts("No");
    29         }
    30     }
    31     return 0;
    32 }
  • 相关阅读:
    对象进行比较
    java中length,length(),size()区别
    引用数据类型、自定义类
    java方法
    学员信息管理系统案例
    商品库存管理查看增减
    引用数据类型Scanner,Random
    Cantor表巧妙的做法
    UVA 11292 The dragon of Loowater勇士斗恶龙 11729 突击战 Commando War
    期末,祝不挂
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/7257372.html
Copyright © 2020-2023  润新知