zoukankan      html  css  js  c++  java
  • Codeforces Round #268 (Div. 1) 题解

    A:24 Game

    题意:给一个n,求从1到n通过加减乘除得到24的方法。

    题解:不难想到n<4时候肯定是无解的,

    n=4时候  1+2=3   3+3=6   6*4=24

    n=5时候1*5=5 5-2=3 3+3=6 6*4=24

    当n>5时候我们可以让n-(n-1)=1 1*1=1 这样就把1~n变成了1~n-2

    所以对于任意给定的n,我们把(5~n)这段的数相邻的相减变成1最终转换成用1~4或者1~5构造答案即可。

     1 #include <cstdio>
     2 
     3 #include <cmath>
     4 
     5 #include <iostream>
     6 
     7 #include <algorithm>
     8 
     9 #include <cstring>
    10 
    11 
    12 
    13 using namespace std;
    14 
    15 int n;
    16 
    17 void work(int x)
    18 
    19 {
    20 
    21     if (x==4) 
    22 
    23     {
    24 
    25         printf("1 + 2 = 3
    3 + 3 = 6
    4 * 6 = 24
    ");
    26 
    27         return;
    28 
    29     }
    30 
    31     if (x==5)
    32 
    33     {
    34 
    35         printf("1 * 5 = 5
    5 - 2 = 3
    3 + 3 = 6
    6 * 4 = 24
    ");
    36 
    37         return;
    38 
    39     }
    40 
    41     printf("%d - %d = 1
    1 * 1 = 1
    ",x,x-1);
    42 
    43     work(x-2);
    44 
    45 }
    46 
    47 int main()
    48 
    49 {
    50 
    51     scanf("%d",&n);
    52 
    53     if (n<4)
    54 
    55     {
    56 
    57         printf("NO
    ");
    58 
    59         return 0;
    60 
    61     }
    62 
    63     printf("YES
    ");
    64 
    65     work(n);
    66 
    67     return 0;
    68 
    69 }
    View Code

    B:Two Sets

    题意:给出n个数p1~pn 要求把这N个数划分成两个集合,要求若X∈A 则a-x∈A 若X∈B 则b-x属于B,a,b为给定得数。

    题解:用一个map记录每个数是否出现过,若对于某个pi a-pi不在这列数中,我们就只能把pi放到B集合中,所以用一个队列记录必然出现在B集合中的数,

    每次取出队头元素X,检查b-X是否在p中出现,若出现也要加入此队列,再加入b-X的同时易知a-(b-X)必然也只能出现在集合B,也要同时加入队列。

     1 #include <cstdio>
     2 
     3 #include <iostream>
     4 
     5 #include <algorithm>
     6 
     7 #include <cmath>
     8 
     9 #include <cstring>
    10 
    11 #include <queue>
    12 
    13 #include <map>
    14 
    15 using namespace std;
    16 
    17 map<int,int> pos;
    18 
    19 int n,a,b,ans[500000],x[500000];
    20 
    21 int main()
    22 
    23 {
    24 
    25     queue<int> q;
    26 
    27     scanf("%d%d%d",&n,&a,&b);
    28 
    29     for (int i=1;i<=n;++i) 
    30 
    31     {
    32 
    33         scanf("%d",&x[i]);
    34 
    35         pos[x[i]]=i;
    36 
    37     }
    38 
    39     for (int i=1;i<=n;++i)
    40 
    41     {
    42 
    43         if (pos[a-x[i]]==0)
    44 
    45         {
    46 
    47             ans[i]=1;
    48 
    49             q.push(x[i]);
    50 
    51         }
    52 
    53     }
    54 
    55     while (!q.empty())
    56 
    57     {
    58 
    59         int now=q.front();
    60 
    61         q.pop();
    62 
    63         if (pos[b-now]==0) 
    64 
    65         {
    66 
    67             printf("NO
    ");
    68 
    69             return 0;
    70 
    71         }
    72 
    73         if (ans[pos[b-now]]==1) continue;
    74 
    75         ans[pos[b-now]]=1;
    76 
    77         if (pos[a-b+now]!=0)
    78 
    79         {
    80 
    81             ans[pos[a-b+now]]=1;
    82 
    83             q.push(a-b+now);
    84 
    85         }
    86 
    87     }
    88 
    89     printf("YES
    ");
    90 
    91     for (int i=1;i<=n;++i) printf("%d ",ans[i]);
    92 
    93     return 0;
    94 
    95 }
    View Code

    C:Hack it!

    题意:定义f(x)为x的各位数字之和,比如f(1234)=1+2+3+4=10,一个人用如下算法计算

    sum=

     ans = solve(l, r) % a;
    if (ans <= 0)
    ans += a;

    当ans=0时会出现错误,对于给定的a,我们要构造一个L,R来hack他。

    gy神犇给我讲的

    我们来观察l=1 r=1e18的时候的sum值

    l r每当+1的时候 我们发现sum值加了1!因为r加1后后面几位即为l不加1时候的数,所以每次加1即把整个数列往前推了一位,然后r变成了1000...L!于是L,R每往后加1,sum就加1,于是先求出来l=1 r=1e18的sum值后挪(a-sum)次即可!r开到足够大目的在于这样不用考虑进位问题,否则r最前面就不是1,也不能保证后面出现L了。巧妙地构造~

    关于sum的算法:令ai=(1~10^i)-1的sum值

    a1=45

    a2=10*a1+45*10

    ...

    an=10*an-1+45*10^i

    得到an=45*n*10^(n-1) 

    a18=81*1e18

    所以sum=(a18+1)%a;问题得到解决。

     1 #include <cstdio>
     2 
     3 #include <cmath>
     4 
     5 #include <iostream>
     6 
     7 #include <cstring>
     8 
     9 #include <algorithm>
    10 
    11 
    12 
    13 using namespace std;
    14 
    15 typedef long long LL;
    16 
    17 LL l,r,a,ans;
    18 
    19 int main()
    20 
    21 {
    22 
    23     l=1;r=1e18;
    24 
    25     scanf("%I64d",&a);
    26 
    27     ans=((3*(3*(3*(3*(5*(2*((LL)1e17%a))%a)%a)%a)%a)%a)%a+1)%a;
    28 
    29     printf("%I64d %I64d",l+a-ans,r+a-ans);
    30 
    31     return 0;
    32 
    33 }
    View Code
  • 相关阅读:
    FusionCharts ScrollColumn2D图
    Java Web项目部署Tomcat运行出错
    Eclipse部署Java Web项目到Tomcat出错
    JavaScript过滤特殊字符
    pl/sql 在一个程序块里打印日志输出到表格
    Java中过滤出字母、数字和中文的正则表达式
    pl/sql 程序块里打印问题
    C++函数的Boost内存池性能介绍
    boost内存池的使用介绍
    内存管理 Boost::singleton_pool
  • 原文地址:https://www.cnblogs.com/zscnash/p/4155432.html
Copyright © 2011-2022 走看看