字典全排序--用next_permutation
题目描述
输入一个可能含有重复字符的字符串,打印出该字符串中所有字符的全排列。
输入
单组测试数据,输入数据是一个长度不超过10个字符的字符串,以逗号结尾。
输出
打印出该字符串中所有字符的全排列。以字典序顺序输出,用空格分隔。
样例输入
abc,样例输出
abc acb bac bca cab cba
字符全排列
#include <iostream>
#include<algorithm>
using namespace std;
int main() {
string str;
cin>>str;
str.erase(str.end() - 1);
sort(str.begin(),str.end());
do{
cout<<str<<" ";
}while(next_permutation(str.begin(),str.end()));//next_permutation()会取得[first,last)所标示之序列的下一个排列组合,如果没有下一个排列组合,便返回false;否则返回true。
return 0;
}
数字全排列
#include <iostream>
#include<algorithm>
using namespace std;
int main(int argc, char** argv) {
int a[4]={1,2,3,4};
sort(a,a+4);
do{
//cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]<<endl;
for(int i=0;i<4;i++)
cout<<a[i]<<" ";
cout<<endl;
}while(next_permutation(a,a+4));
return 0;
}
直接算出集合{1, 2, ..., m}的第n个排列?
#include <iostream>
#include<algorithm>
using namespace std;
int main(int argc, char** argv) {
int a[7]={1,2,3,4,5,6,7};
sort(a,a+7);
int n=1;
do{
if(n==3){
for(int i=0;i<7;i++)
cout<<a[i];
cout<<endl;
break;
}
n++;
}while(next_permutation(a,a+7));
return 0;
}
#include<bits/stdc++.h>
//using namespace std;
//
//int path[10];
//int state[10];//记录数字是否被用过
//
//int n;
//
//void dfs (int u)//第u个格子装数据
//{
// if(u>n)
// {
// for(int i=1;i<=n;i++)
// {
// cout<<path[i]<<" ";
//
// }
// cout<<endl;
//
// }
//
//
//
// for(int i=1;i<=n;i++)
// {
// if(!state[i])
// {
// path[u]=i;
// state[i]=1;
// dfs(u+1);
// state[i]=0;//回溯,还原状态
//
// }
// }
//}
//
//int main()
//{
// cin>>n;
// dfs(1);
跳台阶
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
输入
多组测试样例。每组测试样例包含一个整数n。(1<=n<=100)
输出
每组测试样例输出一行,表示青蛙跳上n级台阶的跳法数量.
所得到的结果模1000000007
#include <bits/stdc++.h>
using namespace std;
long long a[110]; //必须用长整型存,后期跳台阶数目会很大
int n;
int main()
{
a[1]=1;
a[0]=1; //本来a[0]应该是0,分析一下a[2]=2,a[1]+a[0]=1,不符合实际,所以边缘条件要调整一下
for(int i=2;i<=100;i++)
a[i]=(a[i-1]+a[i-2])%1000000007; //取模,避免越界
while(cin>>n)
{
cout<<a[n]<<endl;
}
}
最长公共子串(数据范围比较小,不用优化)
题目描述
一个字符串A的子串被定义成从A中顺次选出若干个字符构成的串。如A=“cdaad" ,顺次选1,3,5个字符就构成子串" cad" ,现给定两个字符串,求它们的最长共公子串。
输入
第一行两个字符串用空格分开。两个串的长度均小于2000 。
输出
最长子串的长度。
线性dp
#include<iostream>
#include<algorithm>
using namespace std;
string word1;
string word2;
int n1,n2;
int s[2000][2000];
void dp()
{
for (int i = 1; i <= n1; i++)
{
for (int j = 1; j <= n2; j++)
{
if (word1[i-1] == word2[j-1])
{
s[i][j] = s[i - 1][j - 1]+1;
//s[i][j]代表当word1长度为i,word2长度是j时,最长公共子串长度
//DP在从长度从小往大存
}
else
{
s[i][j] = max(s[i - 1][j], s[i][j - 1]);
}
}
}
}
int main()
{
cin>>word1>>word2;
n1=word1.length();
n2=word2.length();
dp();
cout << s[n1][n2];//
}
最长上升子序列
#include<iostream>
using namespace std;
int h[1000][4];
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>h[i][1];
h[i][2]=1;
h[i][3]=1;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<i;j++)
{
if(h[j][1]<h[i][1]&&h[i][2]<=h[j][2]) h[i][2]=h[j][2]+1;
if(h[j][1]>h[i][1]&&h[i][3]<=h[j][3]) h[i][3]=h[j][3]+1;
}
}
int maxx=0;
for(int i=0;i<n;i++)
{
maxx=max(maxx,h[i][2]);
maxx=max(maxx,h[i][3]);
}
cout<<maxx;
}
前缀和
#include<iostream>
using namespace std;
int n,L,r,t,ans=0;
int A[605][605]={0};
int sum[605][605]={0};
bool judgeBlack(int x,int y)
{
int maxx = min(n, x+r);
int maxy = min(n, y+r);
int minx = max(1, x-r);
int miny = max(1, y-r);
int s = sum[maxx][maxy] - sum[maxx][miny-1] - sum[minx-1][maxy] + sum[minx-1][miny-1];
int count = (maxx-minx+1)*(maxy-miny+1);
double test = s/(double)count;
return test<=t;
}
int main()
{
cin>>n>>L>>r>>t;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>A[i][j];
sum[i][j] = sum[i-1][j]+sum[i][j-1] - sum[i-1][j-1]+A[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
if(judgeBlack(i,j))
ans++;
}
cout<<ans;
return 0;
}
跳跃游戏二
题目描述
给定一个非负整数数组,假定你的初始位置为数组第一个下标。数组中的每个元素代表你在那个位置能够跳跃的最大长度。你的目标是到达最后一个下标,并且使用最少的跳跃次数。例如:A = [2,3,1,1,4],到达最后一个下标的最少跳跃次数为 2。(先跳跃11步,从下标0到1,然后跳跃3步,到达最后一个下标。一共两次)
输入
第一行输入一个正整数n(1≤n≤100),接下来的一行,输入n个整数,表示数组A。
输出
最后输出最少的跳跃次数。