搜索练习题【题解】

  • VIJOS-P1026 毒药解药
    • Description
    • Sample Input
    • Sample Output
    • HINT
    • Source
    • Solution
  • POJ3321Apple Tree
    • Description
    • Input
    • Output
      • Sample Input
      • Sample Output
    • Source
    • Solution
  • POJ3764The xor-longest Path
    • Description
    • Input
    • Output
      • Sample Input
      • Sample Output
    • Hint
    • Solution

VIJOS-P1026 毒药?解药?

Description

羽毛笔和im是抽签到同一个考场的,她们突然闻到一阵刺鼻的化学试剂的气味。
机灵鼠:(头都不抬)你们是考生么?还在门口磨蹭什么?快进来帮我忙!!……怎么还不进来?你们拖赛,拖赛,把你们的青春都拖掉赛……
im:开…开策了> _<
羽毛笔:哎呀~~机灵鼠大人要我们帮什么忙?^^
机灵鼠:你们看这里的这些药,都是我研制的对付各种症状的解药。可是我一个不小心,每种药都小小地配错了一点原料,所以这些药都有可能在治愈某些病症的同时又使人患上某些别的病症……(im:那…那是解药还是毒药啊?!)……经过我天才的努力(背景:我是天才!!),终于弄清了每种药的具体性能(路人甲:那是你自己配的吗?-_-),我会把每种药能治的病症和能使人患上的病症列一张清单给你们,然后你们要根据这张清单找出能治愈所有病症的最少药剂组合……顺便说一声,病症的数目不超过10种(小呆:偶是好人吧^^),我的药是用不完的,就是说每种药剂都可以被重复使用。给你们的单子里第一行是病症的总数n,第二行是药剂的种类m(0< m< =100),以下有m行,每行有n个数字用空格隔开,文件的第i+2行的n个数字中,如果第j个数为1,就表示第i种药可以治愈病症j(如果患有这种病的话则治愈,没有这种病则无影响),如果为0表示无影响,如果为-1表示反而能使人得上这种病(无病患上,有病无影响)。我制的药任何两种性能都不同。你们只要给我用的最少的药剂数就可以了。给你们个样例:

Sample Input

3
2
1 0 1
-1 1 0

Sample Output

2

HINT

其实还有可能用尽了所有的药也不能将所有病治愈(真是不好意思嗬^^bb),那样的话你们只要写上“The patient will be dead.”就可以了。 im:做不出来啊哇啊啊啊(暴走中) 羽毛笔:哎呀~~im……来来吃药了。^^

Source

VIJOS


状态压缩BFS

Solution:

很显然我们首先会得到一个N*M的表格,表示第i种要对于第j种症状的作用效果。当N等于3的情况,可以得到如下的几种状态:

×
12 3
21 3
31 2
1 23
1 32
2 31
1 2 3
1 2 3

一共会有8中状态,同理 可以得到更普遍的结论:N种病共有 2N 种状态;
这样我们就会有两种方法:
方法一
若状态i可以转移成状态j,则i->j 可以建一条有向边。然后跑最短路就好。
但是说着简单,其实还是有很多注意事项的。先上代码:
Code:

#include <stdio.h>
#include <string.h>
#include <queue>
#define MAXN 1<<(10)+1
using namespace std;
int n,m,st,ed;
int a[150][15],dep[MAXN],visit[MAXN];
void spfa(int src)
{memset(dep,0x3f,sizeof(dep));dep[src]=0;queue<int>Q;Q.push(src);while(!Q.empty()){int u=Q.front();Q.pop();for(int i=1;i<=m;i++){int tmp=u;for(int j=1;j<=n;j++){   if((tmp&(1<<(j-1)))&&a[i][j]==1)    // 二进制情况下,第j位为 1 : - > 有病 //并且当前药物可以治疗 {tmp-=1<<(j-1);                  //让 第 j 位变成 0 }if((!(tmp&(1<<(j-1))))&&a[i][j]==-1){tmp+=1<<(j-1);}}if(dep[tmp]>dep[u]+1)   //当前情况达到 tmp 的步数 能 更新 {dep[tmp]=dep[u]+1;if(!visit[tmp]){visit[tmp]=1;Q.push(tmp);                    }}}}
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){scanf("%d",&a[i][j]);}}st=0,ed=(1<<n)-1;spfa(ed);if(dep[0]==0x3f3f3f3f){puts("The patient will be dead.") ; }else printf("%d\n",dep[0]);return 0;
}

解释与说明
用二进制表示,假设一共有N种病,令111…1(N个1)表示所有病都患,0就是没有病,则st=0,ed=(1 < < N )-1就是N个1 的十进制表示。
然后BFS时只要判断st能不能转移到ed就可以。
PS:位运算大法Newbility
方法二
Hash表判重,原理同上。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node
{int dep;int b[15];
}list[1<<10+1];
int n,m,st,ed;
int mp[150][15];
bool hash[1<<10+1];
void bfs()
{memset(hash,false,sizeof(hash));st=0,ed=(1<<n)-1;int head=1,tail=1;while(head<=tail){for(int i=1;i<=m;i++){tail++;st=0;for(int j=1;j<=n;j++){if(mp[i][j]==1) list[tail].b[j]=1;if(mp[i][j]==0) list[tail].b[j]=list[head].b[j];if(mp[i][j]==-1)list[tail].b[j]=0;if(list[tail].b[j]==1)  st+=(1<<(j-1));}if(!hash[st]){hash[st]=true;list[tail].dep=list[head].dep+1;if(st==ed){printf("%d\n",list[tail].dep);exit(0);}}else tail--;}head++;}
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){scanf("%d",&mp[i][j]);}}bfs();printf("The patient will be dead.\n");return 0;
}

POJ3321【Apple Tree】

Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 21614 Accepted: 6563

Description

There is an apple tree outside of kaka’s house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been carefully nurturing the big apple tree.

The tree has N forks which are connected by branches. Kaka numbers the forks by 1 to N and the root is always numbered by 1. Apples will grow on the forks and two apple won’t grow on the same fork. kaka wants to know how many apples are there in a sub-tree, for his study of the produce ability of the apple tree.

The trouble is that a new apple may grow on an empty fork some time and kaka may pick an apple from the tree for his dessert. Can you help kaka?

Input

The first line contains an integer N (N ≤ 100,000) , which is the number of the forks in the tree.
The following N - 1 lines each contain two integers u and v, which means fork u and fork v are connected by a branch.
The next line contains an integer M (M ≤ 100,000).
The following M lines each contain a message which is either
“C x” which means the existence of the apple on fork x has been changed. i.e. if there is an apple on the fork, then Kaka pick it; otherwise a new apple has grown on the empty fork.
or
“Q x” which means an inquiry for the number of apples in the sub-tree above the fork x, including the apple (if exists) on the fork x
Note the tree is full of apples at the beginning

Output

For every inquiry, output the correspond answer per line.

Sample Input

3
1 2
1 3
3
Q 1
C 2
Q 1

Sample Output

3
2

Source

POJ Monthly–2007.08.05, Huang, Jinsong


DFS序【树状数组维护】

Solution:

以下图为例:

DFS序:

对图进行深度优先遍历时,按访问顶点的先后次序得到的顶点序列称为该图的深度优先遍历序列,或简称为DFS序列

所以对于上图来说,它的DFS序可以是 1 3 6 2 4 5也可以是1 2 4 5 3 6
对于一个点来说,它会有两个时间戳,一个进栈的时间戳一个出栈的时间戳,用in[i],out[i]表示

iin[i]out[i]
116
246
323
466
555
633

然后我们就可以发现,在DFS序中in[i]~out[i]的数字就是i的子树编号。
所以我们就需要处理出来in[],out[]数组然后用树状数组维护增减以及求和就好了。
Code:

#include <stdio.h>
#include <string.h>
#define MAXN 150000
struct node
{int from;int to;int next;
}edge[MAXN];
int n,m,cnt,tot,tmp;
int head[MAXN],c[MAXN],order[MAXN],in[MAXN],out[MAXN];
bool judge[MAXN];
void init()
{memset(head,-1,sizeof(head));cnt=1;
}
void addedge(int from,int to)
{edge[cnt].from=from;edge[cnt].to=to;edge[cnt].next=head[from];head[from]=cnt++;
}
int lowbit(int x)
{return x&(-x);
}
int get_sum(int x)
{int sum=0;while(x){sum+=c[x];x-=lowbit(x);}return sum;
} 
void update(int x,int val)
{while(x<=MAXN){c[x]+=val;x+=lowbit(x);}
}
void dfs(int u)
{in[u]=++tot;    //进入 时间戳 order[tot]=u;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;dfs(v);}out[u]=tot;     //退出 时间戳 
}
int main()
{init();scanf("%d",&n);for(int i=1;i<=n-1;i++){int a,b;scanf("%d%d",&a,&b);addedge(a,b);}dfs(1);for(int i=1;i<=n;i++){update(i,1);judge[i]=true;}/*for(int i=1;i<=tot;i++){printf("%d:",i);for(int j=in[i];j<=out[i];j++){printf("%d ",order[j]);}printf("\n");}*/ scanf("%d",&m);char s[3];for(int i=1;i<=m;i++){scanf("%s %d",s,&tmp);if(s[0]=='Q'){printf("%d\n",get_sum(out[tmp])-get_sum(in[tmp]-1));}else {if(judge[tmp]==false){update(in[tmp],1);judge[tmp]=true;}else{update(in[tmp],-1);judge[tmp]=false;   }}}return 0;
}

POJ3764【The xor-longest Path】

Description

In an edge-weighted tree, the xor-length of a path p is defined as the xor sum of the weights of edges on p:

⊕ is the xor operator.

We say a path the xor-longest path if it has the largest xor-length. Given an edge-weighted tree with n nodes, can you find the xor-longest path?  

Input

The input contains several test cases. The first line of each test case contains an integer n(1<=n<=100000), The following n-1 lines each contains three integers u(0 <= u < n),v(0 <= v < n),w(0 <= w < 2^31), which means there is an edge between node u and v of length w.

Output

For each test case output the xor-length of the xor-longest path.

Sample Input

4
0 1 3
1 2 4
1 3 6

Sample Output

7

Hint

The xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4)


Solution:

异或的性质:a^b=(a^c)^(b^c);
所以可以把根节点当做c,即 i - > j 路径上的Xor
F(i,j)=F(1,i) ^ F(1,j)
F(i,j) 可以通过搜索处理出来。 但是O(N^2)的枚举肯定会超时,所以可以用01字典树来把一个数用二进制的形式储存起来,这样就会得到一个深度最大为32的01树。
Time complexity:O( n*log2( Max(Xor[i,z]) ) )=**O(n*30),**0<=i < n

然后用类似贪心的思想从最高按位查找直到最低位,每一位查找时,如果树中有其当前互异的值存在,则累加该位的权值,并按此方向往下一位查找;否则不累加权值,并按Xor[i,z]的该位上的数字进入下一层。最终累加得到的值即为所求最大值。

#include <stdio.h>
#include <string.h>
#define MAXN 100100
typedef long long ll;
struct node
{ll from;ll to;ll next;ll val;
}edge[MAXN<<1];
ll n,cnt,v,size=1,ans=-1;
ll head[MAXN],dis[MAXN],next[3000000][2];
ll max( ll a , ll b ){ return a > b ? a : b ; }
void init()
{memset(head,-1,sizeof(head));memset(next,0,sizeof(next));memset(dis,0,sizeof(dis));ans=-1,size=cnt=1;
}
void addedge(ll from,ll to,ll val)
{edge[cnt].from=from;edge[cnt].to=to;edge[cnt].val=val;edge[cnt].next=head[from];head[from]=cnt++;
}
void dfs(ll x,ll fa,ll d)
{dis[x]=d;for(ll i=head[x];i!=-1;i=edge[i].next){if((v=edge[i].to)!=fa){dfs(v,x,d^edge[i].val);}}
}
ll newnode()
{memset(next[size],0,sizeof(next[size]));return size++;
}
void Insert(ll x)
{ll p=0;bool index;for(ll i=31;i>=0;i--)   //从高位开始 贪心{index=x&(1ll<<i)?1:0;   //获得x二进制上第 i+1 位的数字 if(!next[p][index])     //如果未开空间 {next[p][index]=newnode();}p=next[p][index];       // 指针后移 进入下一层 } 
}
void find(ll x)
{ll p=0,w=0;bool index;for(ll i=31;i>=0;i--){index=x&(1ll<<i)?0:1;//获得x二进制上第i+1位数字的 非if(next[p][index]){w|=1ll<<i;      //加上该位的权值 p=next[p][index];     } else p=next[p][!index];}ans=max(ans,w);
}
int main()
{while(~scanf("%lld",&n)){init();for(ll i=1;i<=n-1;i++){ll a,b,c;scanf("%lld%lld%lld",&a,&b,&c);a++,b++;addedge(a,b,c);addedge(b,a,c);}dfs(1,0,0);for(ll i=1;i<=n;i++){Insert(dis[i]);find(dis[i]);}printf("%lld\n",ans);}return 0;
} 
/*
4
0 1 3
1 2 4
1 3 6
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/58578.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

表格数据统计与分析

开发工具与关键技术&#xff1a;VS MVC 作者&#xff1a;李光辉 撰写时间&#xff1a;2019.6.8 今天要介绍的是layui表格数据的统计与分析&#xff0c;如下图所示&#xff0c;根据这边的表格数据通过计算得到右边的数据表格。首先我们需要对表格数据进行查询以及筛选&#x…

问卷与量表数据分析(SPSS+AMOS)学习笔记(三) : 数据分析工具,三线表的制作

课程链接&#xff1a;问卷与量表数据分析&#xff08;SPSSAMOS&#xff09; 目录 1. 数据分析工具的种类 2. SPSS窗口介绍 3. SPSS csv文件导入方式 4. SPSS输出为三线表 4.1 简单描述性统计过程 4.2 三线表软件配置 4.3 永久输出三线表格式 4.4 wordexcel 生成三线表…

问卷调查的数据如何分析?

一、模型框架 设计模型框架 一般在正式分析前&#xff0c;研究者常常需要构建模型框架&#xff0c;基于模型框架进行分析研究&#xff0c;例如数据分析、原理研究等等。那么如何构建基础的模型框架&#xff0c;以下以‘笔记本电脑购买意愿影响因素’来进行举例说明。 ​ 模型框…

网上赚钱竞争那么激烈你一定要有自己的绝活!

为何互联网赚钱的项目都存在红利这个说法呢&#xff1f;什么是红利期呢&#xff1f;就是大家都不知道的时候&#xff0c;我们称为红利期&#xff01;当大家都知道这件事情能赚钱那么就不能赚钱啦&#xff01; 其实现在互联网竞争激烈&#xff0c;这是众所周知的事情&#xff0…

申宝正规股票下周市场将迎来抛压

大盘在外围股市普遍上涨的带动下&#xff0c;两市大盘高开高走&#xff0c;盘中虽然振幅不大&#xff0c;沪市上下最大振幅只有16个点&#xff0c;但两市个股走势较比较活跃&#xff0c;盘面上&#xff0c;特高压、量子科技、电子烟、胎压测试、智能电网等板块涨幅靠前&#xf…

申宝策略-多只高位人气股尾盘炸板

三大指数均跌超1%多只高位人气股尾盘炸板&#xff0c;午后指数震荡走低&#xff0c;三大指数均扩大跌幅。盘面上&#xff0c;预制菜板块午后维持强势&#xff0c;国联水产20CM连续涨停&#xff0c;盖世食品涨超10%&#xff0c;华天酒店、金陵饭店、西安饮食、海欣食品、春雪食品…

申宝股票-A股再度跳水

早盘沪深两市分化明显&#xff0c;沪市冲高回落&#xff0c;深市震荡回调。但是相同点是小盘股表现强于权重股。市场热点围绕国防军工、软件、汽车、通讯、水泥建材等行业展开&#xff1b;病毒防治题材、电子烟概念展开调整。 午后&#xff0c;日经指数与恒生指数跌幅加深&…

【筹码分析】改版通达信PAVE筹码引力分析个股强势区和走势

指标公式描述 【筹码分析】改版通达信PAVE筹码引力分析个股强势区和走势 温馨提示&#xff1a;该指标特价&#xff0c;福利&#xff0c;大道至简&#xff0c;原生原理&#xff0c;容易理解&#xff0c;无培训辅导&#xff0c;见下图诊断分析个股。无选股公式。 指标作用&#x…

顶底突破同花顺副图指标 波浪类指标

我代码里面哪一个字是广告&#xff1f;&#xff1f;&#xff1f; 主力:ZIG(3,100/10),colorred,LINETHICK1; 分时2:ZIG(3,2),colorgreen,LINETHICK1; G:MA(主力,3),colorred; D:EMA(主力,34),colorgreen; J:EMA(主力,144),colorligreen; DRAWICON(CROSS(主力,G),主力-0.1,…

ChatGPT热潮席卷全球,会是企业数智化转型良机吗?

互联网沉默已久&#xff0c;ChatGPT的出现激起千层浪&#xff0c;沉寂已久的互联网迎来新一轮的机遇。毫不夸张地说&#xff0c;任何一家以技术见长的企业&#xff0c;人工智能绝对占有一席之地。 人工智能很强悍 ChatGPT可广泛应用于多种对话问答场景&#xff0c;包括智能客服…

大语模型前世今生

引言&#xff1a;席卷世界的大语言模型浪潮 2022年11月30日&#xff0c;OpenAI公司发布了ChatGPT。这迅速成为了社会各界关注的焦点&#xff0c;ChatGPT能够如此快速&#xff0c;准确的完成文本生成&#xff0c;信息抽取&#xff0c;机器翻译&#xff0c;甚至代码生成等复杂任务…

chatgpt赋能python:Python如何解方程——一名有10年Python编程经验工程师的解读

Python如何解方程——一名有10年Python编程经验工程师的解读 Python作为一种通用编程语言&#xff0c;具有强大的数学计算功能&#xff0c;因而被广泛应用于科学计算领域。对于一些需要求解方程的问题&#xff0c;Python也提供了简便的解决方法。本篇文章将介绍Python如何解方…

chatgpt赋能python:Python二次方程求解——一场简单的数学游戏

Python二次方程求解 —— 一场简单的数学游戏 作为一门广受欢迎的编程语言&#xff0c;Python 不仅仅在科学计算、数据分析、人工智能等方面被广泛应用&#xff0c;也被用于数学计算。本篇文章将介绍如何使用 Python 解决二次方程。 什么是二次方程&#xff1f; 一般情况下&…

chatgpt赋能Python-python_conjugate

Python Conjugate: 什么是共轭&#xff1f; 在数学中&#xff0c;共轭是指复数的一种操作。对于一个复数 a b i a bi abi&#xff0c;它的共轭为 a − b i a - bi a−bi。这个操作对于许多数学问题十分重要&#xff0c;因为它可以帮助我们解决求根、求导和求复函数值等问题…

chatgpt赋能python:Python中的非运算:理解not运算符的应用

Python中的非运算&#xff1a;理解not运算符的应用 在Python编程中&#xff0c;非运算(not)是一个常用的逻辑运算。它可以对一个表达式或变量进行逻辑反转。非运算符可以将True转换为False&#xff0c;将False转换为True&#xff0c;因此它在编程中十分重要。本文将介绍非运算…

chatgpt赋能python:Python怎么求解方程

Python怎么求解方程 在数学中&#xff0c;求解方程是一种基本的技能。Python作为一种广泛应用于科学计算和数据分析领域的编程语言&#xff0c;可以帮助我们求解各种类型的方程。Python提供了多个库和函数&#xff0c;使得求解方程在Python中变得非常轻松。 一元方程求解 一…

chatgpt赋能python:Python编程计算一元二次方程——最简单的方法实现

Python编程计算一元二次方程——最简单的方法实现 前言 Python编程语言是一种优秀的开源编程语言&#xff0c;具有易于学习、代码简洁明了、易于维护等优点&#xff0c;因此在近年来得到了广泛的应用。 本文将介绍如何使用Python编写一个简单而又实用的计算一元二次方程的程…

chatgpt赋能python:求一元二次方程Python程序--解题利器

求一元二次方程Python 程序 – 解题利器 一元二次方程是中学阶段数学必修内容&#xff0c;学生们需要掌握如何求解一元二次方程。在实际运用中&#xff0c;求解一元二次方程也经常被用到。今天我们将谈到使用 Python 编写一元二次方程程序。 什么是一元二次方程&#xff1f; …

chatgpt赋能python:用Python编程实现一元二次方程求解过程

用Python编程实现一元二次方程求解过程 介绍 一元二次方程是初中数学中常见的一种方程形式&#xff0c;其如下所示&#xff1a; 其中&#xff0c;a、b、c为实数且 a ≠ 0 a\neq0 a0。 在本文中&#xff0c;我们将会使用Python编程语言实现一元二次方程的求根过程&#xff…

chatgpt赋能python:一元二次方程如何用Python编写?

一元二次方程如何用 Python 编写&#xff1f; 一元二次方程是一种高中数学常见的存在。但是&#xff0c;有时候我们需要使用计算机来解决实际的问题&#xff0c;也需要通过代码实现一元二次方程的求解。本文介绍如何用 Python 编写一元二次方程求解代码。 什么是一元二次方程…