一、双指针
1、给你一个n,给你n个数,再给一个val,去掉所有等于val的值。
思路:当i和j位置都是非val值,i++,j++
当i位置是val,j++
当i是val,j是非val,交换,i++,j++
当j走到最后一个位置的时候,停了,输出0~i位置的值。
代码:
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++){
cin>>a[i];
}
int val;
cin>>val;
int i=0,j=0;
while(j<n){
if(a[i]!=val&&j!=val){
i++;
}else if(a[i]==val&&a[j]!=val){
a[i]=a[j];
a[j]=val;
i++;
}
j++;
}
for(int k=0;k<i;k++){
cout<<a[k]<<" ";
}
题目:给定一个非负整数n,判断是否存在两个整数a和b,a*a+b*b=n。
思路:双指针,两边往中间试。
x*x+y*y>n,y--
x*x+y*y<n,x++
代码:
int n;
cin>>n;
int a=1,b=sqrt(n);
while(a<b){
if(a*a+b*b>n){
b--;
}else if(a*a+b*b<n){
a++;
}else{
cout<<a<<" "<<b;
return 0;
}
}
cout<<"no";
题目:给你一个n,输入n个数字(非递减),返回每个数字平方之后的新数组,非递减的。
思路:用绝对值从两边二分对比,谁大排在后,谁小排在前。
代码:
int n;
cin>>n;
int a[n];
int x=0,y=n-1;
for(int i=0;i<n;i++){
cin>>a[i];
}
int ans[n];
int i=n-1;
while(y>=x){
if(abs(a[x])>=abs(a[y])){
ans[i]=a[x]*a[x];
x++;
}else{
ans[i]=a[y]*a[y];
y--;
}
i--;
}
for(int i=0;i<n;i++){
cout<<ans[i]<<" ";
}
二、递归
马走日:
思路:把重复走到同一个点的情况直接套用过来,省时间。
代码:
int n,m;
int board[31][31];
int xs,ys;
int x[4]={-1,1,0,0};
int y[4]={0,0,1,-1};
bool pass[51][51];
char s[51][51];
int way[1001];
int nn;
void search(int heng,int zong,int step){
if(step==nn){
s[heng][zong]='*';
return;
}
int heng1=heng,zong1=zong;
for(int i=0;i<51;i++){
heng1+=x[way[step]];
zong1+=y[way[step]];
if(heng1<0||heng1>=n||zong1>=m||zong1<0){
break;
}
if(pass[heng1][zong1]==0){
break;
}
search(heng1, zong1, step+1);
}
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>s[i][j];
if(s[i][j]=='.'){
pass[i][j]=1;
}else if(s[i][j]=='X'){
pass[i][j]=0;
}else{
pass[i][j]=1;
xs=i;
ys=j;
}
}
}
cin>>nn;
for(int i=0;i<nn;i++){
string str;
cin>>str;
if(str=="NORTH"){
way[i]=0;
}else if(str=="SOUTH"){
way[i]=1;
}else if(str=="EAST"){
way[i]=2;
}else{
way[i]=3;
}
}
search(xs,ys,0);
s[xs][ys]='.';
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cout<<s[i][j];
}
cout<<endl;
}