2104.10.29模拟赛【奶牛编号】

2.奶牛编号

【问题描述】

作为一个神秘的电脑高手,Farmer John 用二进制数字标识他的奶牛。 
    然而,他有点迷信,标识奶牛用的二进制数字,必须只含有K位“1”

(1 <= K <= 10)。 当然,每个标识数字的首位必须为“1”。 
    FJ按递增的顺序,安排标识数字,开始是最小可行的标识数字

(由“1”组成的一个K位数)。 
    不幸的是,他没有记录下标识数字。请帮他计算,第N个标识数字

(1 <= N <=
10^7)。

【输入】

第1行:空格隔开的两个整数,N和K。

【输出】

如题,第N个标识数字

【输入输出样例】


cowids.in


cowids.out


7 3


10110

输出第n大的包含k个1的01串。

首先第一位必须是1,所以后面还有k-1个1要放。k=1的时候直接特判。

在长度为len的01串中放入k-1个1的方案数就是C(len,k-1)

如果n比C(len,k-1)大,那么len++,n-=C(len,k-1)。继续找下一个。

这样就确定了后面有几位。

然后直接暴力出奇迹不解释

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<queue>
 8 #include<deque>
 9 #include<set>
10 #include<map>
11 #include<ctime>
12 #define LL long long
13 #define inf 0x7ffffff
14 #define pa pair<int,int>
15 #define pi 3.1415926535897932384626433832795028841971
16 using namespace std;
17 int n,k,now;
18 int a[100000];
19 inline LL C(int n,int m)
20 {
21     LL sum=1;
22     for (int i=n-m+1;i<=n;i++)
23       sum*=i;
24     for (int i=1;i<=m;i++)
25       sum/=i;
26     return sum;
27 }
28 inline void work(int n,int rnk)// 长度为n的01串有k个1的字典序rnk小的方案
29 {
30     for (int i=n-k+1;i<=n;i++)a[i]=1;
31     rnk--;
32     while (rnk--)
33     {
34         int tot=0,fst;for (fst=n;fst>=1;fst--)if (a[fst])break;
35         for (;fst>=1;fst--)
36         {
37             if (!a[fst])break;
38             tot++;
39         }
40         for (int i=n;i>=fst;i--)a[i]=0;
41         for (int i=n;i>=n-tot+2;i--)a[i]=1;
42         a[fst]=1;
43     }
44     for (int i=1;i<=n;i++) printf("%d",a[i]);
45 }
46 int main()
47 {
48     freopen("cowids.in","r",stdin);
49     freopen("cowids.out","w",stdout);
50     scanf("%d%d",&n,&k);
51     if (k==1)
52     {
53         printf("1");
54         for(int j=1;j<n;j++)printf("0");
55         return 0;
56     }
57     k--;
58     now=k;
59     while (1)
60     {
61         if (n<=C(now,k))
62         {
63             printf("1");
64             work(now,n);
65             return 0;
66         }
67         n-=C(now,k);
68         now++;
69     }
70 }

cowids

时间: 2024-10-12 14:24:26

2104.10.29模拟赛【奶牛编号】的相关文章

10.2模拟赛总结

10.2 模拟赛总结 T1. 数位dp: 一个非常非常非常非常显然的数位 DP \([L,R] = [1,R]-[1,L-1]\) 所以是分别求两次小于等于某个数字的方案数 \(f(i,j,k)\) 表示从低位数起的第 \(i\) 位,按照规则计算后答案为 \(j\quad (j=0,1)\) \(k\) 表示只考虑后面结尾和 \(lmt\)后面几位 的大小关系 \((k=0,1)\) 考虑第 \(i+1\) 位,算一下新构成的数字并判断下大小就可以了 注意到 \(L,R\) 数据范围特别大,需

10.22 模拟赛

10.22 模拟赛 T1 染色 考虑每个连通块删成一棵树就好了. mmp场上就我路径压缩写炸.... #include<iostream> #define MAXN 200006 using namespace std; int n , m; int fa[MAXN] , siz[MAXN] , book[MAXN] , sz[MAXN]; int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); } int main() {

10.31 模拟赛

10.31 模拟赛 A LIS 考虑每个数字前从 $ m $ 降序构造到 $ a_i $ 即可. #include <iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<vector> using namespace std; #define MAXN 300006 int n , m , k; int A[MAXN]; vector<int&g

10.5模拟赛

这么多模拟赛都没整理,能整理一天算一天吧qaq T1题面 sol:应该不难吧,分别对横坐标和纵坐标取差的绝对值,易知:如果互质就可以看到,否则就不行.然后出题人很毒瘤要用unsigned long long. #include <cstdio> #include <algorithm> using namespace std; long long x1,y1,x2,y2,c1=0,c2=0; unsigned long long x,y; unsigned long long AB

10 01模拟赛订正

好吧,这是我第一次写模拟赛的订正,主要是有时间而且这次的题确实好... 第一题确实好,用的算法人人都会,就是看你能不能想到,我考只打了O(n^4)的暴力,最后还苦逼的MLE,爆零了... 暴力就不多说了...枚举两个点更新其他的点... 其实我考场上思考的是,能被标记的点都与其他的点有什么联系,可惜,除了模拟题目的做法,就不会了... 那让我们就认真地思考一发:我们设A(x1,x2),B(x2,c2),C(x3,c3)来更新D点,只有:有两个点横坐标相等,有两个点纵坐标相等,才可以更新出来一个新

2019.10.24模拟赛赛后总结

本文原创,如果有不到位的地方欢迎通过右下角的按钮私信我! A.Icow Player 题目描述 被无止境的农活压榨得筋疲力尽后,Farmer John打算用他在MP3播放器市场新买的iCow来听些音乐,放松一下.FJ的iCow里存了N(1 <= N <= 1,000)首曲子,按1..N依次编号.至于曲子播放的顺序,则是按一个Farmer John自己设计的算法来决定: * 第i首曲子有一个初始权值R_i(1 <= R_i <= 10,000). * 当一首曲子播放完毕,接下来播放的

2017/9/29模拟赛

T1.多米诺骨牌(card)小 Z 最近买了很多很多的多米诺骨牌,他选出了其中的一些排成了一排,并且准备从右到左碰倒这些骨牌.每个骨牌有一个坐标 xi(>=1)和一个大小 yi(>=1),倒下时将会碰倒坐标区间位于[xi-yi,xi)内的所有骨牌.当然没有两个骨牌有相同的坐标, 并且小 Z 规定坐标大的更靠右.但是他发现他买的骨牌太巨了,所以在倒下的时候会将所有碰倒的骨牌破坏掉,被破坏掉的骨牌就无法使用了,并且不会倒下.得知这个消息的小 Z 十分惊讶,他想知道如果还按刚才这种方法从右到左碰倒所

10.1 模拟赛

由于算错了inf 又ak失败了 过于菜 T1 年轮蛋糕 loj 2758 题目大意: n个数构成的环 把这个环分成三段 使最小的最大 求这个最小段的和的最大值 思路: 可以想到二分 因为log方可以过 所以可以二分长度后lower_bound找断点 或者使用滑动窗口 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cma

10.27 模拟赛

这一次终极被吊打 甚至没进前十 T2 最后改错 T3 没写正解 T1 elim 题目大意: n 行 m 列的游戏棋盘,一行或一列上有连续 三个或更多的相同颜色的棋子时,这些棋子都被消除 当有多处可以被消除时,这些地方的棋子将同时被消除 求消除后的棋盘 思路: sb模拟 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cm