题目
记录找最大最小,注意!运算符的优先级问题
#include
#include
#include
#define rep(i,a,b) for(int i=(a); i<(int)(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(int)(b);++i)
int main()
{
int n;
scanf("%d",&n);
rep(i,0,n)
{
char c[105];
int arr[26],tot1=0,tot2=0;
memset(arr,0,sizeof(arr));
scanf("%s",c);
rep(i,0,strlen(c))
++arr[c[i]-'a'];
std::sort(arr,arr+26);
tot1=arr[25];
tot2=arr[std::upper_bound(arr,arr+26,0)-arr];
int ch=tot1-tot2,flag=0;
if(ch==1||ch==0)
{
printf("No Answer\n0\n");
continue;
}
_rep(i,2,sqrt(ch))
if(!(ch%i))
flag=1;
if(flag)
printf("No Answer\n0\n");
else
printf("Lucky Word\n%d\n",ch);
}
return 0;
}
题目
找二进制的一,方法很多,这里给出位运算法, 扩展
#include
#define rep(i,a,b) for(int i=(a); i<(int)(b);++i)
int fun(int a)
{
int k=0;
while(a)
{
a=a&(a-1);
++k;
}
return k;
}
int main()
{
int n;
scanf("%d",&n);
rep(i,0,n)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
printf("%d %d %d %d\n",fun(a),fun(b),fun(c),fun(d));
}
return 0;
}
题目
注意一下不要用int除,会有除不尽的方案
#include
#define rep(i,a,b) for(int i=(a); i<(int)(b);++i)
int main()
{
int n;
scanf("%d",&n);
rep(i,0,n)
{
int m,x,y,z;
scanf("%d %d %d %d",&m,&x,&y,&z);
int t=1.0*x*m/(y-x);
float ans=z*t;
printf("%.2f\n",ans);
}
return 0;
}
题目
这个题最开始做是写的递归,因为出口找不到试了很多很多次也不对,后来去查的发现是bfs,还是自己思考的少(本来就蒟蒻还不动脑子,没救了),不光是递归出口找不到,而且在我写递归的时候还在念叨找到就结束找到就结束,这不就是bfs嘛,对自己学过的东西没有印象,没有总结过每种方法的特点,做题依然抓瞎。
这题有很多的方法,先上bfs的
#include
#include
#define rep(i,a,b) for(int i=(a); i<(int)(b);++i)
using namespace std;
const int maxn=100001;
int n,k,book[maxn],step[maxn];
void bfs()
{
int head,next;
q.push(n);
step[n]=0;
book[n]=1;
while(!q.empty())
{
head=q.front();
q.pop();
rep(i,0,3)//三方向
{
switch(i)
{
case 0:next=head+1;break;
case 1:next=head-1;break;
case 2:next=head*2;break;
}
if(next>=0&&next<=maxn&&!book[next])
{
q.push(next);
book[next]=1;
step[next]=step[head]+1;
if(next==k)
{
printf("%d\n",step[k]);
break;
}
}
}
}
}
int main()
{
scanf("%d %d",&n,&k);
if(n>=k)
printf("%d\n",n-k);
else
bfs();
return 0;
}
正着递归(数大输出不了答案),这样写有很多不好考虑到的情况,比如把移动顺序改一改可能就输出不了
#include
int n,k,ans=0x3f3f3f3f;
int book[100005];
void fun(int pos,int step)
{
if(pos<0||step>ans||pos>2*k||book[pos])
return;
if(pos==k)
{
if(step<ans)
ans=step;
return;
}
book[pos]=1;
if(pos>k)
fun(pos-1,step+1);
fun(pos+1,step+1);
book[pos]=0;
fun(pos-1,step+1);
book[pos]=0;
fun(pos*2,step+1);
}
int main()
{
scanf("%d %d",&n,&k);
if(n>=k)
printf("%d\n",n-k);
else
{
fun(n,0);
printf("%d\n",ans);
}
return 0;
}
反着递归,也就是从终点向起点递归,写多了会发现其实这个题还是二分的,找最近的偶数,看是先减步数少还是先加步数少,反着递归应该也能避免顺序问题
#include
int n,k,ans=0x3f3f3f3f;
int book[100005];
void fun(int pos,int step)
{
if(pos<0||book[pos]||step>ans)
return;
if(pos==n)
{
if(step<ans)
ans=step;
return;
}
book[pos]=1;
if(pos%2==0)
fun(pos/2,step+1);
fun(pos+1,step+1);
book[pos]=0;
fun(pos-1,step+1);
}
int main()
{
scanf("%d %d",&n,&k);
if(n>=k)
printf("%d\n",n-k);
else
{
fun(k,0);
printf("%d\n",ans);
}
return 0;
}
这种方法稍大一点数也能通过,不过再大也是运行不出来(是不是爆栈了???)
爆炸那改成尾递归试试(我不会写,这是腾大佬给我发的,还没看懂)
#include
#include
int n,k;
int fun(int pos)
{
if(n>=pos)//递归终点
return n-pos;
if(pos%2==0)
return std::min(pos-n,fun(pos/2)+1);//看是减半离的近还是直接减离的近
else
return std::min(fun(pos+1),fun(pos-1))+1;
}
int main()
{
scanf("%d %d",&n,&k);
printf("%d\n",fun(k));
return 0;
}
这个数大也能对,就是理解不了(为啥加1啊,加1就是次数吗?脑补:因为最后找到返回的是0,所以加1也确保一定是最小的,于是这里加1就可以代表次数了。昨天刚写了分治,今天就不会了)
还要感谢范学长的指导
所以bfs才是这题最好的解法(蒟蒻的微笑( ^ _ ^ ))
之所以bfs和递归差这么大,其实就是bfs只会把合法的点加入判断序列,而递归中所有的点都在序列里,虽然会被return但是数量实在太大,所以运行很成问题
题目
标准dfs,也就是填色法,一个负数代表一种颜色,用负数不用正数就是防止给你的矩阵里有别的正数
#include
#include
#define rep(i,a,b) for(int i=(a); i<(int)(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(int)(b);++i)
const int maxn=100+5;
const int dir[4][2]={0,1,1,0,0,-1,-1,0};
int n,m,maze[maxn][maxn],book[maxn][maxn];
void dfs(int x,int y,int id)
{
rep(k,0,4)
{
int tx=x+dir[k][0];
int ty=y+dir[k][1];
if(tx<1||tx>n||ty<1||ty>m)
continue;
if(book[tx][ty]||!maze[tx][ty])
continue;
book[tx][ty]=id;
dfs(tx,ty,id);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(book,0,sizeof(book));
memset(maze,0,sizeof(maze));
scanf("%d %d",&n,&m);
_rep(i,1,n)
_rep(j,1,m)
scanf("%d",&maze[i][j]);
int cnt=0;
_rep(i,1,n)
_rep(j,1,m)
if(maze[i][j]==1&&book[i][j]==0)
dfs(i,j,--cnt);
printf("%d\n",cnt*(-1));
}
return 0;
}