1.输入两个数n、m,对n进行重新排列,计算重新排列后的数中有多少个可以整除m。
相同的数只能算一次。
1
<
=
n
<
=
1
0
15
,
1
<
=
m
<
=
100
1<=n<=10^{15},1<=m<=100
1<=n<=1015,1<=m<=100
输入:
322 2
输出:
2
由于n最大不超过16位,用字符串s来进行转换,之后对字符串进行全排列得到每一种能够拼成的数字,用一个集合判断该数字是否重复生成,统计所有能够整除m的个数。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL num,m;
string s;
set<LL> se;
int ans;
int main() {
cin>>num>>m;
s=to_string(num);
sort(s.begin(),s.end());
do{
LL t=stoll(s);
if(!se.count(t)){
if(t%m==0){
ans++;
}
se.insert(t);
}
}while(next_permutation(s.begin(),s.end()));
cout<<ans;
return 0;
}
2.n个人,m个房子
每个房子有舒适度和价格,问怎么买房子舒适度总和最大。
确保:
1.每个人最多买一个房子
2.一个房子最多被一个人买
第一行输入n和m,
第二行输入n个人手上有多少钱
后面m行每行为一个房子的舒适度和价格。
2 2
2 2
2 2
2 2
4
贪心思想,用结构体存房子,将价格从小到大排序,舒适度从大到小排序,然后从最小的面额开始匹配,尽可能匹配最大舒适度的情况。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5+10;
int n,m,x,a,b,pos;
struct node{
int shushi,jiage;
bool operator<(const node&p) const{
if(jiage!=p.jiage) return jiage<p.jiage;
return shushi>p.shushi;
}
};
bool st[N];
vector<node> v;
multiset<int> se;
LL ans;
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
cin>>x;
se.insert(x);
}
for(int i=0;i<m;i++){
cin>>a>>b;
v.push_back({a,b});
}
sort(v.begin(),v.end());
for(auto x:se){
for(int i=0;i<v.size();i++){
if(!st[i] && v[i].jiage<=x){
ans+=v[i].shushi;
st[i]=1;
break;
}
}
}
cout<<ans;
return 0;
}
3.给定一个映射:a=1,b=2.…Z=26
请你构造一个数字字符串,恰好有K个只包含小写字母的字符申能映射成这个数字串。
比如K=3,你可以输出"111",因为“aaa”得到数字"111",“ka"或者"ak”也得到是111。
输入一个整数K。输出一个符合要求的数字串。
1
≤
K
≤
1
0
18
1≤K≤ 10^{18}
1≤K≤1018
要求构造的字符串长度不能超过
1
0
5
10^5
105
答案可能有多种,输出任意一种即可,
如果无法构造,输出-1。
这道题相当于力扣第91题的反问形式:
91. 解码方法
4.有一个n×m的迷宫(左上角是(1,1)),#是石块,.是空地,一个人在S处,出口在F。
但是走出迷宫之前需要按顺序去碰指定的石头,所有石头碰完才能出迷宫。只要在石头上下左右相邻的地点就算碰到。
第一行输入n,m,k(需要碰k块石头)
之后n行输入迷宫
之后k行输入需要碰的石头坐标。
输出离开迷宫的最短时间。
输入
3 5 3
#....
####.
FS...
1 1
2 3
2 2
用bfs找距离当前合法的按石头的距离,然后走到这里,更新当前点Sx,Sy,每一步都是最优距离。
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int n,m,k,a,b,Sx,Sy,Tx,Ty,ans;
char g[N][N];
bool st[N][N];
string s;
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
struct node{
int x,y,d;
bool operator<(const node& other) const {
if (x != other.x) {
return x < other.x;
} else if (y != other.y) {
return y < other.y;
} else {
return d < other.d;
}
}
};
int main() {
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
{
cin>>s;
for(int j=1;j<=m;j++)
{
g[i][j]=s[j-1];
if(s[j-1]=='S') Sx=i,Sy=j,g[i][j]='.';
if(s[j-1]=='F') Tx=i,Ty=j,g[i][j]='.';
}
}
k++;
while(k--){
if(k>=1) cin>>a>>b;
else a=Tx,b=Ty;
memset(st,0,sizeof(st));
set<node> se; //用一个se来存储当前所有合法的可以按石头的坐标
for(int i=0;i<4;i++){
int xx=dx[i]+a,yy=dy[i]+b;
if(xx>=1 && xx<=n && yy>=1 && yy<=m && g[xx][yy]=='.'){
se.insert({xx,yy,0});
}
}
queue<node> q;
q.push({Sx,Sy,0});
st[Sx][Sy]=1;
int f=0;
while(q.size()){
auto t=q.front(); q.pop();
for(int i=0;i<4;i++){
int xx=dx[i]+t.x,yy=dy[i]+t.y;
if(xx>=1 && xx<=n && yy>=1 && yy<=m && g[xx][yy]=='.' && !st[xx][yy]){
q.push({xx,yy,t.d+1});
st[xx][yy]=1;
for(auto p:se) {
if(p.x==xx && p.y==yy){
Sx=xx,Sy=yy;
ans+=t.d+1;
f=1;
break;
}
}
if(f) break;
}
}
if(f) break;
}
if(!f){ //如果不能按下当前的石头就说明最终无法到达
cout<<"-1";
return 0;
}
//cout<<ans<<" "<<Sx<<" "<<Sy<<endl;
}
cout<<ans;
return 0;
}