zoukankan      html  css  js  c++  java
  • BestCoder 2nd Anniversary

      1001:只要将一个非零数字拆出来,作为小的那个数,另外的数字从大到小排列组成另外一个数字相加即可。代码如下(细节有点多):

     1 #include <stdio.h>
     2 #include <string.h>
     3 const int N = (int)1e7 + 5;
     4 
     5 char s[N];
     6 int cnt[10];
     7 
     8 bool isok()
     9 {
    10     // 至少要有一个不是0的数字当做第一个数字的开头
    11     for(int i=1;i<=9;i++) if(cnt[i]) return true;
    12     return false;
    13 }
    14 
    15 int main()
    16 {
    17     int T;
    18     scanf("%d",&T);
    19     getchar();
    20     while(T--)
    21     {
    22         memset(cnt,0,sizeof(cnt));
    23         for(;;)
    24         {
    25             char c = getchar();
    26             if(c == '
    ') break;
    27             cnt[c-'0']++;
    28         }
    29         int first=-1;
    30         for(int i=1;i<=9;i++) //找第一个不是0的数字,当做第二个数
    31         {
    32             if(cnt[i])
    33             {
    34                 cnt[i]--;
    35                 first = i;
    36                 break;
    37             }
    38         }
    39         if(!isok())
    40         {
    41             puts("Uncertain");
    42             continue;
    43         }
    44 
    45         int up = first,tot=0;
    46         for(int i=0;i<=9;i++)
    47         {
    48             for(int j=1;j<=cnt[i];j++)
    49             {
    50                 s[tot++] = i + '0';
    51             }
    52         }
    53 
    54         // 模拟加法进位
    55         for(int i=0;i<tot;i++)
    56         {
    57             if(up + s[i]-'0' > 9)
    58             {
    59                 s[i] = s[i] + up - 10;
    60                 up = 1;
    61             }
    62             else
    63             {
    64                 s[i] = s[i] + up;
    65                 up = 0;
    66                 break;
    67             }
    68         }
    69 
    70         if(up == 1) printf("1");
    71         for(int i=tot-1;i>=0;i--)
    72         {
    73             printf("%c",s[i]);
    74         }
    75         puts("");
    76     }
    77 }
    View Code

      1002:见代码(注释很详细了):

     1 #include <stdio.h>
     2 #include <algorithm>
     3 #include <string.h>
     4 using namespace std;
     5 typedef long long ll;
     6 const int N = 100000 + 5;
     7 const int mod = 998244353;
     8 
     9 int a[N],b[N],n;
    10 
    11 ll solve()
    12 {
    13     // 第一个数字的a和b值肯定相等
    14     if(a[1] != b[1]) return 0;
    15     ll ret = 1;
    16     for(int i=2;i<=n;i++)
    17     {
    18         // a值是单调不上升,b值是单调不下降。
    19         // 如果不满足这两条则没有答案
    20         if(a[i]>a[i-1] || b[i]<b[i-1]) return 0;
    21         
    22         int op = (a[i]!=a[i-1]) + (b[i]!=b[i-1]);
    23         // 如果op是2,表示最大值和最小值都发生了改变,
    24         // 也就是说第i个数既是最大值也是最小值,显然不可能
    25         if(op == 2) return 0;
    26         // 如果op是1,这个位置只能放最大值或者最小值改变了的那个值
    27         
    28         // 如果op是0,表示第i个数可以使夹在最大值和最小值内任意一个没被使用过的数
    29         // b[i]-a[i]+1 表示最大值和最小值的这个区间内的数字个数
    30         // i-1 表示在这个区间内已经使用了这么多个数字,它们无法在这个位置出现,应排除
    31         if(op == 0)
    32         {
    33             // 用乘法原理叠加
    34             ret = ret * (b[i]-a[i]+1 - (i-1)) % mod;
    35         }
    36     }
    37     return ret;
    38 }
    39 
    40 int main()
    41 {
    42     int T;
    43     scanf("%d",&T);
    44     while(T--)
    45     {
    46         scanf("%d",&n);
    47         for(int i=1;i<=n;i++) scanf("%d",a+i);
    48         for(int i=1;i<=n;i++) scanf("%d",b+i);
    49         ll ans = solve();
    50         printf("%I64d
    ",ans);
    51     }
    52 }
    View Code

      1003:利用扫描求出答案。具体见代码(有注释):

     1 #include <stdio.h>
     2 #include <algorithm>
     3 #include <string.h>
     4 using namespace std;
     5 typedef long long ll;
     6 const int N = 100000 + 5;
     7 
     8 /*
     9     考虑三角形三条边 a,b,c (a >= b) 的关系 a - b < c, a + b > c ,即 c∈(a-b,a+b)
    10     这是非法区域,只要在L到R上的区间扫描减去非法区域即可
    11 */
    12 
    13 int n,tot;
    14 ll L,R,a[N];
    15 struct node
    16 {
    17     ll l,r;
    18     bool operator < (const node& A) const
    19     {
    20         return l==A.l ? r<A.r : l<A.l;
    21     }
    22 }P[N];
    23 
    24 void solve()
    25 {
    26     // 全集减去非法区域就是答案
    27     ll ans = R - L + 1;
    28     ll left = L;
    29     for(int i=1;i<=tot;i++)
    30     {
    31         if(P[i].r>=left)
    32         {
    33             if(P[i].l>=left)
    34             {
    35                 ans -= P[i].r-P[i].l+1;
    36             }
    37             else ans -= P[i].r-left+1;
    38             left = P[i].r + 1;
    39         }
    40     }
    41     printf("%I64d
    ",ans);
    42 }
    43 
    44 void init()
    45 {
    46     tot = 0;
    47     scanf("%d%I64d%I64d",&n,&L,&R);
    48     for(int i=1;i<=n;i++) scanf("%I64d",a+i);
    49     sort(a+1,a+1+n);
    50     for(int i=2;i<=n;i++)
    51     {
    52         // P区域是非法区域
    53         P[++tot].l = max(L,a[i]-a[i-1]+1); //左右区间都是开区间
    54         P[tot].r = min(R,a[i]+a[i-1]-1);
    55         
    56         // 下面这句一定要有
    57         if(P[tot].l > P[tot].r) tot--;
    58     }
    59     sort(P+1,P+1+tot);
    60 }
    61 
    62 int main()
    63 {
    64     int T;
    65     scanf("%d",&T);
    66     while(T--)
    67     {
    68         init();
    69         solve();
    70     }
    71 }
    View Code
  • 相关阅读:
    session的使用
    不可变对象的魅力
    协变和逆变
    LaTeX 学习小结
    KMP 算法的两种实现
    MySQL MVCC
    Java 并发之 Executor 框架
    Java 动态代理的简单使用和理解
    Java 偏向锁、轻量级锁和重量级锁
    事件循环和协程
  • 原文地址:https://www.cnblogs.com/zzyDS/p/5680541.html
Copyright © 2011-2022 走看看