加一
给定一个整数 n。你需要对它做 m次操作。在一次操作中,你要将这个数的每一位 d 替换成 d+1。比如,1912 在进行一次操作后将变成 21023。
请求出整数 n进行了 m 次操作后的长度。答案可能很大,输出对 10^9+7 取模后的结果。
输入格式
第一行一个整数 t,表示测试单元的个数。
接下来 t 行,每行有两个整数 n 和 m,表示最初的数字和进行多少次操作。
输出格式
对于每个测试单元输出最终数字的长度,答案对 10^9+7取模。
样例输入
5
1912 1
5 6
999 1
88 2
12 100
样例输出
5
2
6
4
2115
数据规模
所有数据保证 1≤t≤2⋅10^5,1≤n≤10^9,1≤m≤2⋅10^5。
对与每一个输入的数字列如 1 9 9 8,如果我们是直接去一个一个算的化,要进行操作数多起来就会很麻烦,那我们反过来向,8进行一个操作变成9,9进行一次操作变成1和0;
我们用一个数组来记录数字的变化,再用一个数组来记录数位;
或者说,我们直接用一个二维数组来记录
a[i][j]表示这个数字进行了i次后,j这个数字的个数
159 进行一次操作
a[1][1]=a[0][2];a[1][5]=a[0][6];a[1][9]=a[0][1]+a[0][0];
1进行一次操作变成2,6进行一次操作变成6,9进行一次操作变成1和0;
我们就能对它进行dp;找到它的关系表达式 :
当j不等于9的时候a[i][j]=a[i-1][j+1]
当j等于9的时候 a[i][9]=(a[i-1][0]+a[i-1][1])%1e9+7;
因为这个数据的大小2*10^5*10够小,我们就能对数据进行预处理
2*10^5个数据,每个数据都是0-9;最多十次;
总共大小最大为2*10^6
#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
const int n=200005;
long long f[n][10];//a[i][j]表示进行i次操作后,j这个数字变成了几位数
int main()
{
int t;
scanf("%d",&t);
for(int i=0;i<10;i++) f[0][i]=1;//没有进行操作,有这个数字的化就是初始的1
for(int i=1;i<=n;i++){//m最大为2e5,可以全部遍历一遍储存答案
for(int j=1;j<=9;j++){
f[i][j-1]=f[i-1][j];
}
f[i][9]=(f[i-1][1]+f[i-1][0])%mod;
}
while(t--){
char s[20];
int m,ans=0;
scanf("%s %d",&s,&m);
int cd=strlen(s);
for(int i=0;i<cd;i++){
int sz=s[i]-'0';
ans+=f[m][sz];
ans%=mod;
}
printf("%ld\n",ans);
}
return 0;
}
//例如0 1 2 3 4 5 6 7 8 9 9进行两次操作
//第一次操作f[1][0]=f[0][1] f[1][1]=f[0][2]...
//f[1][9]=f[0][1]+f[0][0];
跳跳
平面上给定了一些整点(横纵坐标均为整数的点),被称为 “魔法阵”。魔法少女派派想要在各魔法阵之间传送,每一次传送,她将使用下面的方式:
- 刚开始,派派已经位于某传送阵之上;
- 如果派派掌握一种魔法 (A,B),其中 A,B 均为整数。使用一次这个魔法可以让派派从任意整点 (X,Y) 瞬间移动至 (X+A,Y+B);
- 选择一种魔法并开始传送,在一次传送过程中可以使用多次该魔法,但在抵达下一个传送阵之前仅能使用这一种魔法。
问派派至少需要掌握多少种魔法,才能在从任意魔法阵直接传送到任意魔法阵?
输入格式
第一行一个整数 N。
接下来一行 N 行,每行包含两个整数 Xi,Yi, 表示每个魔法阵的坐标。
输出格式
一个数,表示答案。
样例1输入
3
1 1
4 5
1 4
样例1输出
6
解释: 任务是从 (1,1) 传送至 (4,5) 以及 (1,4)、从 (4,5) 传送至 (1,1)以及 (1,4)、从 (1,4) 传送至 (1,1) 以及 (4,5) 。
注意你不能使用 (0,3)+(3,1)的魔法从 (1,1) 到达 (4,5)。因为每次移动,你只能使用一种魔法。
当然,你可以学习 (0,1),那样的话,从 (1,1) 到达 (1,4) 则需要使用 3 次(0,1) 魔法了。
样例2输入
3
1 1
2 2
1000000000 1000000000
样例2输出
2
数据规模
- N∈[10,500]
- Xi,Yi∈[0,10^9], 但保证坐标之间两两不同。
这题看着emmm也不难,我们对于两个点,只需要算他们的距离,用最小的步子去走就行,步子可以小,可以多走一点,到达的点就更多,我的意思是:你可以慢慢来,一步一步地走,只要坚持走下去,能到达的地方会比那些大步流星匆匆走过的人多很多
对于每个点,我们都能进行遍历循环,就是对于第一个点,我们把它到第n个点的步子都记录下来,找到它到每个点的最小步伐,如果这个魔法没用过,我们就把答案++;
再对第二个点到各个点的魔法进行判断;
#include <bits/stdc++.h>//学map
using namespace std;
pair<int,int> dui;
int main(){
int n;
int x,y;
cin>>n;
vector<pair<int,int> > v;//建立一个pair容器
for(int i=0;i<n;i++){
cin>>x>>y;//输入点的坐标
v.push_back({x,y});
}
int ans=0;
map<pair<int,int>, int> ditu;
for(int i=0;i<n;i++){//从这个点到各个点的距离
for(int j=0;j<n;j++){
if(j==i) continue;//再同一点不需要魔法
int dx=v[i].first-v[j].first;//两个点的x坐标差
int dy=v[i].second-v[j].second;//找到两个数的最大公约数
if(dx==0&&dy!=0){//分析特殊的(0,y)(x,0)类型
dy/=fabs(dy);
}
else if(dx!=0&&dy==0){
dx/=fabs(dx);
}
else{
int gys=fabs(__gcd(dx,dy));
dx/=gys;
dy/=gys;//把他们都除以公约数得到最小的步伐
}
if(ditu[{dx,dy}]==0){//这个魔法没有用过
ditu[{dx,dy}]=1;
ans++;
}
}
}//这边已经几下所有的魔法了,下面进行去重
cout<<ans<<endl;
return 0;
}
这边介绍一下stl里面的map
map是一个键值对,和python里面的字典是一个类型的
map<类型(键),类型(值)> 变量名
map可以直接通过它的键来访问值
或者通过迭代器来访问
map<类型,类型> ::iteror it;
it->first访问第一个值,it->second访问第二个值
map.size()获得map的大小
map.find(key)找到key这个键对应的迭代器
map.erase(it)删除it这个迭代器
map.erase(first,last) 删除[first,last)这个区间里面的元素
map.begin() .end()获取开头和结尾
对于两个元神构成的键我们可以用pair<int,int>
并用map[{a,b}]来找去对应的值
可以用insert来创建一个pair类型的map
map.insert(pair<int,int> int);
连续因子
这个题目,我们先找到他的因子,再看因子后面的数是不是也是它的因子,是的话继续,直到出现不是它因子的数,然后把它的长度记录下来,和最大值进行比较,并且把这个串因子的起点也记录下来然后输出就行
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
int n;
cin>>n;
int count=0;
int digit=0;
for(int i=2;i<=sqrt(n);i++){
int sum=1;
int nowcount=0;
int digitnow=i;//记录这个在进行连续的数字
for(int j=i;n%j==0&&n%(sum*j)==0;j++){
sum*=j;
nowcount++;//记录数字连续个数
}
if(nowcount>count){
count=nowcount;
digit=digitnow;
}
}
if(count==0){
cout<<1<<endl;
cout<<n<<endl;
}
else{
cout<<count<<endl;
for(int i=digit;i<digit+count;i++){
if(i==digit+count-1) cout<<i<<endl;
else{
cout<<i<<'*';
}
}
}
return 0;
}