算法合集3.13

简介: 算法合集3.13

bfs

#include<bits/stdc++.h>
using namespace std;
int a[100][100],v[100][100];
struct point{
  int x;
  int y;
  int step;
};
queue<point>r;
int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};
int main(){
  int n,m,startx,starty,p,q;
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
      scanf("%d",&a[i][j]);
    }
  }
  scanf("%d%d%d%d",&startx,&starty,&p,&q);
  point start;
  start.x=startx;
  start.y=starty;
  start.step=0;
  r.push(start);
  v[startx][starty]=1;
  int flag=0;
while(!r.empty()){
int x=r.front().x,y=r.front().y;  
  if(x==p&&y==q){
  flag=1;
  printf("%d",r.front().step);
  break;  
  }
  for(int k=0;k<=3;k++){
    int tx,ty;
    tx=x+dx[k];
    ty=y+dy[k];
    if(a[tx][ty]==1&&v[tx][ty]==0){
      point temp;
      temp.x=tx;
      temp.y=ty;
      temp.step=r.front().step+1;
      r.push(temp);
      v[tx][ty]=1;
    }
  }
  r.pop();
} 
if(flag==0) printf("no answer!"); 
  return 0;
}

dfs

#include<bits/stdc++.h>
using namespace std;
const int N=1e2+10;
int mp[N][N],vis[N][N];
bool fg=false;
int dx[4]={0,0,-1,1};
  int dy[4]={-1,1,0,0};
  int n;
  int sx,sy,ex,ey;
//  bool check(int nx,int ny){
//  if(nx>0&&nx<n&&ny>0&&ny<=n&&vis[nx][ny]!=false&&mp[nx][ny]==0){
//    return true;
//  } 
//  return false;
//  }
void dfs(int x,int y){
  if(vis[x][y]||fg)return;
  vis[x][y]=true;
  if(x==ex&&y==ey){
    fg=true;
    return;
  }
  for(int i=0;i<4;++i){
    int nx=x+dx[i];
    int ny=y+dy[i];
    if(nx>0&&nx<=n&&ny>0&&ny<=n&&vis[nx][ny]==false&&mp[nx][ny]==0){
      dfs(nx,ny);
    }
  }
}
int main(){
  cin>>n;
  for(int i=1;i<=n;++i){
    for(int j=1;j<=n;++j){
      cin>>mp[i][j];
    }
  }
  cin>>sx>>sy>>ex>>ey;
  if(mp[sx][sy]==1){
    puts("NO");
    return 0;
  }
  dfs(sx,sy);
  puts(fg?"YES":"NO");
  return 0;
}

并查集

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 10051005;
int m,n,k,pre[maxn],ans;
bool vis[maxn];
void init()
{
  memset(vis,0,sizeof(vis));
  for(int i=1;i<=n*m;i++)
    pre[i] = i; 
}
int find(int x)  
{
  if(x!=pre[x])
    return pre[x] = find(pre[x]);
  return x;
}
void join(int x,int y)
{
  int xx = find(x);
  int yy = find(y);
  if(xx!=yy)
  {
    pre[yy] = xx;
  }
}
int main()
{
  scanf("%d%d%d",&n,&m,&k);
  init();
  for(int i=0;i<k;i++)
  {
    int x,y;
    scanf("%d%d",&x,&y);
    join(x,y);
  }
  for(int i=1;i<=n*m;i++)
  {
    vis[find(i)] = 1;
//    cout<<pre[i]<<" "<<find(i)<<endl;
  }
  for(int i=1;i<=n*m;i++)
    ans += vis[i];
  cout<<ans<<endl;
  return 0;
}


大数加法


7-5 a+b(正长小数版) (5 分)


给定两个正的小数a,b,求a,b之和。需要注意的是,这两个小数的有效数字位数比较多,最大有100位有效数字。


输入格式:

两行,分别表示正小数a,b。该小数一定带有小数点。


输出格式:

两者之和。如果结果小数存在末尾0,均保留。


输入样例:

0.9999999999999999999999999999999999999999999999999999999999

0.0000000000000000000000000000000000000000000000000000000001

输出样例:

1.0000000000000000000000000000000000000000000000000000000000

#include<stdio.h>
#include<string.h>
int search(char a[]){
  int i=0;
  while(a[i]!='.'){
    i++;
  }
    return i;
}
int main(){
  char a[220],b[220],m[220];
  int pa,pb,pc,stra,strb;
  int i,j,n;
  gets(a);
  gets(b);
  stra=strlen(a)-1;
  strb=strlen(b)-1;
  pa=search(a);
  pb=search(b);
  pc=pb;
  if(pa>=pb){strcpy(m,a);pc=pa;}
  else strcpy(m,b);
  int xiao=stra-pa,zeng=pa;
  if(pa>pb)zeng=pb;
  if(stra-pa>=strb-pb){
    xiao=strb-pb;
    for(n=stra-pa;n>0;n--){
      i=n+pc;
      j=n+pa;
      m[i]=a[j];
    }
  }
  else for(n=strb-pb;n>0;n--){
    i=n+pc;
    j=n+pb;
    m[i]=b[j];
  }
//  printf("xiao=%dpc=%d\n",xiao,pa);
  //¼Ó·¨
  int t=0;
   for(;xiao>0;xiao--){
    i=pa+xiao;
    j=pb+xiao;
    n=pc+xiao;
    m[n]=a[i]+b[j]-'0'+t;
         t=0;
    if(m[n]>'9'){m[n]-=10;t=1;}
   }
   int k;
   for(k=1;k<=zeng;k++){
    i=pa-k;
    j=pb-k;
    n=pc-k;
    m[n]=a[i]+b[j]-'0'+t;
         t=0;
    if(m[n]>'9'){m[n]-=10;t=1;}
   }
   if(t==1)for(--n;n>=0;n--){
    m[n]=m[n]+t;
    t=0;
    if(m[n]>'9'){m[n]-=10;t=1;}
   }
   if(t==1&&n==-1)printf("1");
   puts(m);
}

标题:机器人繁殖

X星系的机器人可以自动复制自己。它们用1年的时间可以复制出2个自己,然后就失去复制能力。

每年X星系都会选出1个新出生的机器人发往太空。也就是说,如果X星系原有机器人5个,

1年后总数是:5 + 9 = 14

2年后总数是:5 + 9 + 17 = 31

如果已经探测经过n年后的机器人总数s,你能算出最初有多少机器人吗?



数据格式:


输入一行两个数字n和s,用空格分开,含义如上。n不大于100,s位数不超过50位。

要求输出一行,一个整数,表示最初有机器人多少个。


例如:

用户输入:

2 31

则程序应该输出:

5

再例如:

用户输入:

97 2218388550399401452619230609499

则程序应该输出:

8

资源约定:

峰值内存消耗 < 512M

CPU消耗  < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0

注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。

注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。


提交时,注意选择所期望的编译器类型。

#include<iostream>
#include<cmath>
using namespace std;
int main(){
    //需要注意,这里可能会用到大数运算,但非常神奇的就是这里的double居然不会出错
    double s;
    int n, k;
    cin >> n >> s;
    k = (s-n-1)/(pow(2, n+1) -1) +1;
    cout << k;
    return 0;
}


从X星截获一份电码,是一些数字,如下:

13

1113

3113

132113

1113122113

....


YY博士经彻夜研究,发现了规律:

第一行的数字随便是什么,以后每一行都是对上一行“读出来”

比如第2行,是对第1行的描述,意思是:1个1,1个3,所以是:1113

第3行,意思是:3个1,1个3,所以是:3113


请你编写一个程序,可以从初始数字开始,连续进行这样的变换。


输入


第一行输入一个数字组成的串,不超过100位

第二行,一个数字n,表示需要你连续变换多少次,n不超过20


输出一个串,表示最后一次变换完的结果。


输出


输出一个串,表示最后一次变换完的结果。



样例输入


5

7

样例输出


13211321322115

#include<iostream>
#include<string.h>
#include<string>
using namespace std;
int main()
{
  char code[10000];
  memset(code, '\0', sizeof(code));       // 注意要初始化
  char codetmp[10000];
  memset(codetmp, '\0', sizeof(codetmp)); // 注意要初始化
  int index = 0;
  int n;
  cin >> code;
  int len = strlen(code);
  cin >> n;
  char start;
  int num = 0;
  while (n--)       // 这个while循环针对code数组
  {
    bool flag = 0;
    start = code[0];    // 标记当前连续的那个字符
    index = 0;   num = 0;
    len = strlen(code);
    for (int i = 0; i<len; i++)
    {
      if (code[i]==start)    // 如果 当前字符==当前连续字符
        num++;
      if (i == len-1)        // 如果已经是最后一个字符了
        flag = 1;
      if (code[i]!=start)
      {
        /* 先把个数num和字符start存起来 */
        codetmp[index++] = num + '0';   // codetmp是字符数组,所以要加上'0'
        codetmp[index++] = start;
        /* 再把当前连续字符换成code[i] */
        start = code[i];
        num = 1;
      }
    }
    if (flag) // 如果已经是最后一个字符,因为我们还没有存num和start,得操作如下
    {
      codetmp[index++] = num + '0';
      codetmp[index++] = start;
    }
         /* 因为要保证while循环针对code数组,这里把codetmp数组复制到code数组 */
    int t_len = strlen(codetmp);
    for (int i = 0; i<t_len; i++)
      code[i] = codetmp[i];
  }
  cout << code << endl;
//  system("pause");
}

题目描述


X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。

某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?


已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。

例如:

A + - + -

- + - - +

- + + + -

+ - + - +

B + - + -


坦克车只能水平或垂直方向上移动到相邻的区。



输入


输入第一行是一个整数n,表示方阵的大小, 4<=n<100

接下来是n行,每行有n个数据,可能是A,B,+,-中的某一个,中间用空格分开。

A,B都只出现一次。


输出


要求输出一个整数,表示坦克从A区到B区的最少移动步数。

如果没有方案,则输出-1



样例输入


5

A + - + -

- + - - +

- + + + -

+ - + - +

B + - + -

样例输出


10

#include <bits/stdc++.h>//万能头文件
using namespace std;
char Map[101][101]; //地图数组
bool Vis[101][101]; //标记数组 标记是否走过
int Next[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; //方向数组 遍历方向
typedef struct node { //定义结构体数组,便于操作调用 包含坐标,步数,符号
  int x, y, step;
  char flag;
} node;
node n[10001]; //BFS数组一般是m*m,再开大一点
int main() {
  int m;
  cin >> m;
  getchar(); //吃掉回车
  int head, tail, x, y, tx, ty;
  for (int i = 1; i <= m; i++) {
    for (int j = 1; j <= m; j++) {
      scanf("%c", &Map[i][j]);
      if (Map[i][j] == 'A') { //记下起点位置的坐标
        x = i, y = j;
      }
      getchar(); //吃掉空格和回车
    }
  }
  head = tail = 1; //初始化 BFS可以理解为一个队列,头和尾
  n[head].x = x;
  n[head].y = y;
  n[head].step = 0;
  n[head].flag = ' ';
  Vis[x][y] = 1; //标记起点位置为走过了
  tail++;
  while (head < tail) { //BFS核心
    for (int i = 0; i < 4; i++) { //遍历4个方向
      tx = n[head].x + Next[i][0];
      ty = n[head].y + Next[i][1];
      if (tx > m || ty > m || tx < 1 || ty < 1) //出边界
        continue;
      if (Vis[tx][ty] == 0 && n[head].flag != Map[tx][ty]) { //没走过且符合+-
        Vis[tx][ty] = 1;
        n[tail].flag = Map[tx][ty];
        n[tail].x = tx;
        n[tail].y = ty;
        n[tail].step = n[head].step + 1;
        tail++;
      }
    }
    if (n[head].flag == 'B') { //走到终点
      cout << n[head].step << endl;
      return 0;
    }
    head++;
  }
  cout << "-1"; //走不到终点
  return 0;
}

111

222     333

333

333331

444

5555

666

777

相关文章
|
11天前
|
供应链 算法
【算法】——快排,分治算法合集
本文主要介绍排序中的快排思想的应用,做到一法通万法的效果
|
11天前
|
算法 容器
【算法】——双指针算法合集(力扣)
移动零,复写零,快乐数,盛最多水的容器,有效三角形的个数,和为s的两个数(查找总价格为目标值的两个商品 ),三数之和,四数之和
|
8月前
|
C++
【剑指offer】-重建二叉树-04/67
【剑指offer】-重建二叉树-04/67
|
存储 算法 测试技术
剑指offer-6.重建二叉树
剑指offer-6.重建二叉树
29 0
|
Perl
剑指offer 06. 重建二叉树
剑指offer 06. 重建二叉树
54 0
|
人工智能 算法
ACM算法训练【双指针算法合集】
思路: 找到i,j的单调性,统一向后移动,使时间复杂度为O(2n) 枚举i,每次看j是否需要向后走,得到最长的长度
95 1
ACM算法训练【双指针算法合集】
重建二叉树(剑指offer 07)
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
106 0
重建二叉树(剑指offer 07)
|
C++
【力扣·每日一题】630. 课程表 III (C++ 贪心 优先队列)
【力扣·每日一题】630. 课程表 III (C++ 贪心 优先队列)
67 0
【力扣·每日一题】630. 课程表 III (C++ 贪心 优先队列)
|
机器学习/深度学习 C++ Perl
剑指offer——重建二叉树
剑指offer——重建二叉树
111 0
剑指offer——重建二叉树

热门文章

最新文章