思维 进制转换 数位DP 无前导0 T3
Problem - 1811E - Codeforces
从一个不含有数字4的递增序列中找第k个数并输出。
如 \(1,2,3,5,6,7,8,9,10,11,12\), \(k = 4\) 时输出 \(5\)。
有一个巧妙的解法:
考虑这个问题, 从一个没有限制的从1开始的递增序列找出第k个数, 显然就是十进制的k。而这里则可以定义新的进制为 "012356789" 9进制, 那么k对应的就是这个特殊的九进制数, 我们只需要把它转换为十进制就行。
二转十:
while(k)
ans += k % 2, k /= 2;
九转十:
while(k)
ans += k % 9, k /= 9;
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
using LL = long long;
int a[20];
int cnt = 0;
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
string s = "012356789";
int T;
cin >> T;
while (T--)
{
LL k;
cin >> k;
cnt = 0;
while (k)
a[cnt++] = s[k % 9] - '0', k /= 9;
for (int i = cnt - 1; i >= 0; i--)
cout << a[i];
cout << endl;
}
}
也可以考虑数位DP, 定义 \(f(i,j)\) 为长度为i, 且最高位为j的数, 可以写出这样的初始化函数来得到 \([1,i]\) 的满足条件的数的个数:
void init()
{
for (int i = 0; i <= 9; i++)
if (i != 4)
f[1][i] = 1;
for (int i = 2; i <= N - 1; i++)
{
for (int j = 0; j <= 9; j++)
{
if (j == 4)
continue;
for (int k = 0; k <= 9; k++)
f[i][j] += f[i - 1][k];
}
}
}
然后再实现查找前缀和 \([1,num]\) 的满足条件的数的个数, 题目中的 \(k\) 最大为 1e12, 直接二分结果, 找最左边且 \(dp(mid) = k\) 的值就是最终结果。
记得要处理前导0, 方法是在首尾不加上0开头的部分, 最后再加一遍所有长度小于 num.size() 的部分。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <vector>
using namespace std;
const int N = 17;
typedef long long ll;
const ll INF = 1e17;
ll f[N][10];
void init()
{
for (int i = 0; i <= 9; i++)
if (i != 4)
f[1][i] = 1;
for (int i = 2; i <= N - 1; i++)
{
for (int j = 0; j <= 9; j++)
{
if (j == 4)
continue;
for (int k = 0; k <= 9; k++)
f[i][j] += f[i - 1][k];
}
}
}
ll dp(ll x)
{
if (!x)
return 0;
vector<int> nums;
while (x)
nums.push_back(x % 10), x /= 10;
ll res = 0;
for (int i = nums.size() - 1; i >= 0; i--)
{
int x = nums[i];
for (int j = (i == nums.size() - 1); j < x; j++)
res += f[i + 1][j];
if (x == 4)
break;
if (!i)
res++;
}
for (int i = 1; i <= nums.size() - 1; i++)
for (int j = 1; j <= 9; j++)
res += f[i][j];
return res;
}
int main()
{
init();
int T;
cin >> T;
while (T--)
{
ll k;
cin >> k;
ll l = -1, r = 1e13;
while (l != r - 1)
{
ll mid = l + r >> 1;
if (dp(mid) < k)
l = mid;
else
r = mid;
}
cout << r << endl;
}
return 0;
}
moduleAdefself.funcputs"func"endend>>A.funcfunc>>A::funcfunc为什么.和::都存在?为什么不仅是.? 最佳答案 作用域解析运算符(::)可以解析常量、实例方法和类方法,因此只要我们在正确的位置查找,我们就可以将该运算符用于基本上任何方法。此外,由于方法“func”被定义为模块A的类方法(通过self.func,类似于“静态”方法)它直接属于模块(即本身是一个对象)所以它可以用点运算符调用,模块作为接收者。请注意,模块A的实例对“func”没有任何可见性,因为它是一个类方法:a
慢跑者与狗问题描述一个慢跑者在平面上沿椭圆以恒定的速率𝒗=𝟏跑步,设椭圆方程为:𝒙=𝟏𝟎+𝟐𝟎𝒄𝒐𝒔(𝒕),𝒚=𝟐𝟎+𝟓𝒔𝒊𝒏(𝒕)。突然有一只狗攻击他,这只狗从原点出发,以恒定速率𝒘跑向慢跑者,狗的运动方向始终指向慢跑者。分别求出𝒘=𝟐𝟎,𝒘=𝟓时狗的运动轨迹。模型建立设时刻t慢跑者的坐标为(𝑿(𝒕),𝒀(𝒕)),狗的坐标为(𝒙(𝒕),𝒚(𝒕))。则𝑿=𝟏𝟎+𝟐𝟎𝒄𝒐𝒔(𝒕),𝒀=𝟐𝟎+𝟏𝟓𝒔𝒊𝒏(𝒕),狗从(0,0)出发,建立狗的运动轨迹的参数方程:由于狗始终对准人,因而狗的速度方向平行于狗与人位置的差向量:消去𝝀,得由题意𝑿=𝟏𝟎+𝟐𝟎𝒄𝒐𝒔𝒕,𝒀=𝟐𝟎+1𝟓𝒔𝒊𝒏(𝒕),狗从(0,0)
我有一种情况需要这样调用:classOfficeattr_accessor:workers,:iddefinitialize@workers=[]enddefworkersworkertype=worker.typeresp=Worker.post("/office/#{@id}/workers.json",:worker=>{:type=>type})worker=Worker.new()resp.to_hash.each_pairdo|k,v|worker.send("#{k}=",v)ifworker.respond_to?(k)endself.workersworker类(Cl
我有两个非常相似的模型Pretreatment和Diagnosis,属于模型Patient:classPretreatment在Patient显示页面上,我显示了两种形式,一种用于预处理,另一种用于诊断:我的问题是如何将这两个表单放在一起,以便用户只需按一次提交按钮?我不确定,但我认为嵌套属性不是处理它的正确方法,也许是fields_for`标签?更新我尝试使用fields_for标签:但是我得到了错误:undefinedmethod`model_name'forArray:Classin 最佳答案 对关联模型使用fields_fo
spark官方提供了两种方法实现从RDD转换到DataFrame。第一种方法是利用反射机制来推断包含特定类型对象的Schema,这种方式适用于对已知的数据结构的RDD转换; 第二种方法通过编程接口构造一个Schema,并将其应用在已知的RDD数据中。一、反射机制推断Schema实现反射机制Schema需要定义一个caseclass样例类,定义字段和属性,样例类的参数名称会被反射机制利用作为列名objectRddToDataFrameByReflect{//定义一个student样例类caseclassStudent(name:String,age:Int)defmain(args:Array[
给定:functionA(name){this.name=name;}是:vara1=newA("A1");完全等同于:vara1={};A.call(a1,"A1");a1.__proto__=A.prototype;?谢谢 最佳答案 嗯,问题是__proto__是非标准的(link),并非所有实现都支持。:-)除此之外,constructor属性(link)不会被正确设置,您可能必须自己设置。另外,我认为您最好在调用构造函数之前设置原型(prototype)。所以:functionA(name){this.name=name;}
背景我的背景是使用C++为嵌入式设备和桌面开发大规模面向对象的中间件和应用程序。现在我们需要为我们的初创公司创建一个大规模的网络应用程序。问题基于请求-响应和基于持续轮询的当前Web开发框架看起来非常原始,效率低下。我正在寻找完全服务器端面向对象和基于事件的编程。这是一个例子,服务器上有一个名为employeeManager的持久化对象,这个对象的方法,empListgetAllEmployeeList();empListgetEmployeeOfDepartment(stringstrDept);/*Somemore*/这个对象的事件employeeAdded(empID);empl
数字电路逻辑设计 卡诺图目录前言1、什么是卡诺图2、用卡诺图表示逻辑函数的方法 3、利用卡诺图合并最小项的规律4、任意项前言在学习FPGA的时候,关于竞争和冒险的判断方法之一卡诺图法,当时有看到的说法是用卡诺图查看电路是否存在互斥电路。当时很不理解,然后就去看了一下同学的《数字电路逻辑设计》对这个知识点做个记录。1、什么是卡诺图 将真值表转换成方格图的形式,按循环码的规矩来排列变量的取值组合,所得的真值表称为卡诺图。 循环码:相邻两组之间只有一个变量值不同的编码。(是不是觉得很像格雷码,唯一不同的是循环码还有一个条件就是最大的值与最小的值也只有一个变量不同,例如:
这些是创建javascript对象的方法:functionapple(optional_params){this.type="macintosh";this.color="red";this.getInfo=function(){returnthis.color+''+this.type+'apple';};}varapple={type:"macintosh",color:"red",getInfo:function(){returnthis.color+''+this.type+'apple';}}我真的更喜欢后者,因为它是Json语法,但我看到的第一个比后者多。它们在功能上有什么
我正在尝试在sigma.js图形中绘制边DOTTED和CURVED。我正在使用customEdgeShapes和curve插件,但我无法在同一条边上组合两种不同的样式。事实上,我只能将一种样式应用于type属性:edge.type='curvedArrow';或edge.type='dotted';如何将两种样式应用到边缘? 最佳答案 “谢谢你的回答,但我想要一个既弯曲又点缀的边缘。也许唯一的方法是重写插件......–rvandoni”我需要类似的东西,是的,这似乎是唯一的方法。让事情变得简单:添加:context.setLine