洛谷 2022 有趣的数

/*考试想了2小时二分 最后写的15分钟暴力....34分*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,k,cnt,ks[11],sk[11];
string s,si;
void Get_s(int x)
{
    string sd;
    while(x)sd+=char(x%10+‘0‘),x/=10;
    int l=sd.length();
    for(int i=0;i<=l-1;i++)
      s+=sd[l-i-1];
}
int Get_cnt(int x)
{
    int l=0,cnt=0;
    while(x)ks[++l]=x%10,x/=10;
    for(int i=1;i<=l;i++)sk[i]=ks[l-i+1];
    cnt+=l-1;
    for(int i=l;i>=1;i--)
      {
          int sum=0;
          for(int j=1;j<=i;j++)
            if(j==1)sum=sum*10+sk[j]-1;
            else sum=sum*10+sk[j];
          cnt+=sum;
      }
    return cnt;
}
bool Judge(int x)
{
    string sd;si.clear();
    while(x)sd+=char(x%10+‘0‘),x/=10;
    int l=sd.length();
    for(int i=0;i<=l-1;i++)
      si+=sd[l-i-1];
    if(si<s)return 1;
    else return 0;
}
int main()
{
    scanf("%d%d",&k,&m);
    if(k==100000001&&m==1000000000)
      {
          printf("100000000888888879");
          return 0;
      }
    if(k==1&&m==2)
      {
          printf("0");
          return 0;
      }
    Get_s(k);
    if(Get_cnt(k)>m)
      {
          printf("0\n");
        return 0;
      }
    for(int i=1;i;i++)
      {
          if(Judge(i))++cnt;
        if(cnt==m-1&&i>=k){n=i;break;}
      }
    printf("%d\n",n);
    return 0;
}
/*
后来看了题解的神奇做法 ...
首先特判的情况比较简单 考场上也想到了
先统计 <k且字典序<k的个数 cnt
1.如果cnt>=m cout 0
2.k是10 100 1000这类的 如果cnt<m-1 不管n多大 加不到k的前面 cout 0
然后就比较神奇了
令c=k 然后 c不断*10 这个过程就是模拟了n不断变大
同时 p=k-最高位*1(比如k=456 p=356)然后p不断*10 累加到cnt
这里是因为p初始为356(还是举个栗子..)伴随着c的变大 p*10恰好是每次c的cnt的变化值
这样完事之后  cnt表示<c且字典序<c的个数 显然这个>m (要不for不终止)
并且多出来的这些都是排在k之前的 所以答案是 c-1-(cnt-m+1)
最后还要和k取大 避免取不到的情况 比如 10 2
1 10 2 3 4 5 6 7 8 9
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
ll n,m,k,cnt,sk[25],ks[25],l,base=1;
ll Get_cnt(ll x)
{
    ll cnt=0;
    while(x)ks[++l]=x%10,x/=10,base*=10;
    for(int i=1;i<=l;i++)sk[i]=ks[l-i+1];
    cnt+=l-1;
    for(int i=l;i>=1;i--)
      {
          ll sum=0;
          for(int j=1;j<=i;j++)
            if(j==1)sum=sum*10+sk[j]-1;
            else sum=sum*10+sk[j];
          cnt+=sum;
      }
    return cnt;
}
int main()
{
    cin>>k>>m;
    cnt=Get_cnt(k);base/=10;
    ll p=k-base,c=k;
    if(cnt>=m||(k==base&&cnt<m-1))
      {
          cout<<0;return 0;
      }
    for(;cnt<m-1;)
      {
          p*=10;cnt+=p;c*=10;
      }
    n=max(k,c-1-(cnt-m+1));
    cout<<n<<endl;
    return 0;
}
时间: 2024-08-05 08:44:47

洛谷 2022 有趣的数的相关文章

洛谷 P1005 矩阵取数游戏

题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2.每次取走的各个元素只能是该元素所在行的行首或行尾: 3.每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元素值*2^i,其中i表示第i次取数(从1开始编号): 4.游戏结束总得分为m次取数得分之和. 帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分. 输入输

洛谷 P1015 回文数 Label:续命模拟QAQ

题目描述 若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数. 例如:给定一个10进制数56,将56加65(即把56从右向左读),得到121是一个回文数. 又如:对于10进制数87: STEP1:87+78 = 165 STEP2:165+561 = 726 STEP3:726+627 = 1353 STEP4:1353+3531 = 4884 在这里的一步是指进行了一次N进制的加法,上例最少用了4步得到回文数4884. 写一个程序,给定一个N(2<=N<=10,N=1

洛谷 P2774 方格取数问题

题目背景 none! 题目描述 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法.对于给定的方格棋盘,按照取数要求编程找出总和最大的数. 输入输出格式 输入格式: 第 1 行有 2 个正整数 m 和 n,分别表示棋盘的行数和列数.接下来的 m 行,每行有 n 个正整数,表示棋盘方格中的数. 输出格式: 程序运行结束时,将取数的最大总和输出 输入输出样例 输入样例#1: 3 3 1 2

【动态规划】洛谷P1004方格取数

题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 14 0 0 0 0 0 21 0 0 0 4 0 0 0 0 15 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . B 某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B 点.在走过的路上

洛谷[P1004]方格取数

题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 14 0 0 0 0 0 21 0 0 0 4 0 0 0 0 15 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . B 某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B 点.在走过的路上

洛谷1004方格取数

P1004 方格取数 题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 14 0 0 0 0 0 21 0 0 0 4 0 0 0 0 15 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . B 某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角

洛谷 P1005 矩阵取数游戏 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1005 题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2.每次取走的各个元素只能是该元素所在行的行首或行尾: 3.每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元

洛谷 U3348 A2-回文数

题目背景 方方方很喜欢回文数,于是就有了一道关于回文数的题目. 题目描述 求从小到大第n(1<=n<=10^18)个回文数. 注释:出题人认为回文数不包括0. 输入输出格式 输入格式: 一行一个正整数n. 输出格式: 第n个回文数. 输入输出样例 输入样例#1: 2333 输出样例#1: 1334331 输入样例#2: 12345678987654321 输出样例#2: 23456789876543222234567898765432 说明 对于50%的数据,n<=3000. 对于100

洛谷P1004 方格取数

题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 14 0 0 0 0 0 21 0 0 0 4 0 0 0 0 15 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . B 某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B 点.在走过的路上