题目:
很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。
为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。
J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。
聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。
J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?
要点总结:
此题思想比较巧妙,整张地图是树,目的求两个结点之间最长距离(即树的直径)。核心在于获取树的两个端点,分开获取。首先从任意结点开始遍历整棵树,距离这个结点最远的结点一定是树的端点,之后从这个端点再dfs遍历一下树,这时找出最大长度就是两端点距离了。
代码:
#include<bits/stdc++.h>
using namespace std;
vector<vector<int>> arr;
vector<bool> visit;
int maxdis=0;
int maxcity;
int n;
void dfs(int curcity,int curdis){
if(curdis>maxdis){
maxdis=curdis;
maxcity=curcity;
}
visit[curcity]=true;
for(int i=1;i<=n;i++){
if(arr[curcity][i]!=0&&visit[i]==false){
dfs(i,curdis+arr[curcity][i]);
}
}
}
int main(){
cin>>n;
arr.resize(n+1,vector<int>(n+1,0));
visit.resize(n+1,false);
for(int i=1;i<=n-1;i++){
int start,end,weight;
cin>>start>>end>>weight;
arr[start][end]=weight;
arr[end][start]=weight;
}
dfs(1,0);
maxdis=0;
for(int i=1;i<=n;i++){
visit[i]=false;
}
dfs(maxcity,0);
int res=0;
for(int i=0;i<=maxdis-1;i++){
res+=(i+11);
}
cout<<res;
return 0;
}
题目:
给出字符串,判断其是否是回文或镜面回文。
给定一个由数字或字母组成的字符串,如果该字符串正读、反读都一样,则该字符串被称作回文字符串。例如,"ABCDEDCBA"就是回文字符串。
给定一个由数字或字母组成的字符串,将字符串中每个字符转换为对应的镜面字符(有镜面字符)或保持不变(无对应镜面字符),如果转换后的字符串反读的结果与字符串转换前正读的结果相同,则该字符串被称作镜面字符串。例如,"3AIAE"就是镜面字符串。
如果一个字符串既是回文字符串又是镜面字符串,则称该字符串为镜面回文字符串。例如,"ATOYOTA"就是镜面回文字符串。
所有有效字符与其镜面字符见下表:
|----|------|----|------|----|------|
| 字符 | 镜面字符 | 字符 | 镜面字符 | 字符 | 镜面字符 |
| A | A | M | M | Y | Y |
| B | | N | | Z | 5 |
| C | | O | O | 1 | 1 |
| D | | P | | 2 | S |
| E | 3 | Q | | 3 | E |
| F | | R | | 4 | |
| G | | S | 2 | 5 | Z |
| H | H | T | T | 6 | |
| I | I | U | U | 7 | |
| J | L | V | V | 8 | 8 |
| K | | W | W | 9 | |
| L | J | X | X | | |
注意:数字0与字母O视作同一字符,都用字母O表示。
要点总结:
在替换镜面的时候为了避免同一次for循环内部再换回去,每次换完continue一下
代码:
#include<bits/stdc++.h>
using namespace std;
bool ishui(string s){
string s1=s;
reverse(s1.begin(),s1.end());
return s1==s;
}
bool isjin(string s,string temp){
if(ishui(temp)&&s==temp) return true;
else return false;
}
int main(){
string s;
while(getline(cin,s)){
string temp=s;
for(int i=0;i<temp.size();i++){
if(temp[i]=='E'){
temp[i]='3';
continue;
}
if(temp[i]=='J'){
temp[i]='L';
continue;
}
if(temp[i]=='L'){
temp[i]='J';
continue;
}
if(temp[i]=='S'){
temp[i]='2';
continue;
}
if(temp[i]=='Z'){
temp[i]='5';
continue;
}
if(temp[i]=='2'){
temp[i]='S';
continue;
}
if(temp[i]=='3'){
temp[i]='E';
continue;
}
if(temp[i]=='5'){
temp[i]='Z';
continue;
}
}
reverse(temp.begin(),temp.end());
if(!ishui(s)&&!(s==temp)) cout<<s<<" -- is not a palindrome."<<endl<<endl;
if(ishui(s)&&!(s==temp)) cout<<s<<" -- is a regular palindrome."<<endl<<endl;
if(!ishui(s)&&(s==temp)) cout<<s<<" -- is a mirrored string." <<endl<<endl;
if(ishui(s)&&(s==temp)) cout<<s<<" -- is a mirrored palindrome." <<endl<<endl;
}
return 0;
}
题目:
循环数是那些不包括0这个数字的没有重复数字的整数 (比如说, 81362) 并且同时具有一个有趣的性质, 就像这个例子:
如果你从最左边的数字( 记为n,在这个例子中是8) 开始往右边数,一直数n个数字(如果已经到了最右边则回到最左边),你会停在另一个不同的数字上。如果停在一个相同的数字上,这个数就不是循环数。
就像: 8 1 3 6 2 从最左边接下去数8个数字: 1 3 6 2 8 1 3 6 所以下一个数字是6. 重复这样做 (这次从'6'开始数6个数字) 并且你会停止在一个新的数字上: 2 8 1 3 6 2, 也就是2. 再这样做 (这次数两个): 8 1。 再一次 (这次数一个): 3。 又一次: 6 2 8, 这时你回到了起点。
此时,我们数到的数字依次是:8 6 2 1 3,即每一个数字都被数了1次,并且回到了起点。
如果你将每一个数字都数了1次以后没有回到起点, 你的数字不是一个循环数。
给你一个数字 M (在1到9位之间), 找出第一个比 M大的循环数(输入的M保证这个循环数能保存在4位的有符号整数中)。
要点总结:
题目难度不大,细心一点,不要每次char转int的时候都忘记-'0',不然直接按ascall码值转换,排错会花很多时间。
代码:
#include<bits/stdc++.h>
using namespace std;
bool isxun(int n){
string s=to_string(n);
vector<bool> visit(10,false);
for(int i=0;i<s.size();i++){
if(s[i]=='0') return false;
if(visit[s[i]-'0']) return false;
visit[s[i]-'0']=true;
}
for(int i=0;i<s.size();i++){
visit[s[i]-'0']=false;
}
int len=s.size();
int curidx=0;
int curnum=s[0]-'0';
for(int i=0;i<len;i++){
curidx=(curidx+curnum)%len;
curnum=s[curidx]-'0';
if(visit[curnum]==true) return false;
visit[curnum]=true;
}
if(curnum!=s[0]-'0') return false;
return true;
}
int main(){
int m;
cin>>m;
int n=m+1;
while(true){
if(isxun(n)) break;
n++;
}
cout<<n;
return 0;
}
题目:
给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。
问总共有多少种放法?
n小于等于8。
说明:同一条对角线是指包括两条主对角线的所有对角线,n=5时的棋盘从左上往右下有9条对角线,从右上往左下也有9条对角线。
比如,棋盘为:
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
表示一个4*4的棋盘,所有位置都可放皇后。
则可知有2种放法。
要点总结:
一定一定记住,这里return前面要单独写回溯,不要以为下面回溯了并且这里是最后一步了不用回溯,这只是分支走到这里结束了,如果没回溯,其他分支不能走到这,漏情况的
代码:
#include<bits/stdc++.h>
using namespace std;
int n;
int num=0;
vector<vector<int>> board;
vector<bool> blackcol;
vector<bool> blackdui1;
vector<bool> blackdui2;
vector<bool> whitecol;
vector<bool> whitedui1;
vector<bool> whitedui2;
vector<vector<bool>> visit;
void whitedfs(int row,int col){
whitecol[col]=true;
visit[row][col]=true;
whitedui1[row-col+n]=true;
whitedui2[row+col]=true;
if(row==n){
num++;
whitecol[col]=false;
visit[row][col]=false;
whitedui1[row-col+n]=false;
whitedui2[row+col]=false;
return;
}
for(int i=1;i<=n;i++){
if(board[row+1][i]==1&&!visit[row+1][i]&&!whitecol[i]&&!whitedui1[row+1-i+n]&&!whitedui2[row+1+i]){
whitedfs(row+1,i);
}
}
whitecol[col]=false;
visit[row][col]=false;
whitedui1[row-col+n]=false;
whitedui2[row+col]=false;
}
void blackdfs(int row,int col){
blackcol[col]=true;
visit[row][col]=true;
blackdui1[row-col+n]=true;
blackdui2[row+col]=true;
if(row==n){
for(int i=1;i<=n;i++){
if(board[1][i]==1&&!visit[1][i]&&!whitecol[i]&&!whitedui1[1-i+n]&&!whitedui2[1+i]){
whitedfs(1,i);
}
}
blackcol[col]=false;
visit[row][col]=false;
blackdui1[row-col+n]=false;
blackdui2[row+col]=false;
return;
}
for(int i=1;i<=n;i++){
if(board[row+1][i]==1&&!visit[row+1][i]&&!blackcol[i]&&!blackdui1[row+1-i+n]&&!blackdui2[row+1+i]){
blackdfs(row+1,i);
}
}
blackcol[col]=false;
visit[row][col]=false;
blackdui1[row-col+n]=false;
blackdui2[row+col]=false;
}
int main(){
cin>>n;
board.resize(n+1,vector<int>(n+1));
visit.resize(n+1,vector<bool>(n+1,false));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>board[i][j];
}
}
blackcol.resize(n+1,false);
blackdui1.resize(2*n+1,false);
blackdui2.resize(2*n+1,false);
whitecol.resize(n+1,false);
whitedui1.resize(2*n+1,false);
whitedui2.resize(2*n+1,false);
for(int i=1;i<=n;i++){
if(board[1][i]==1&&!visit[1][i]&&!blackcol[i]&&!blackdui1[1-i+n]&&!blackdui2[1+i]){
blackdfs(1,i);
}
}
cout<<num;
return 0;
}
英语翻译:
人工智能辅助医学诊断技术提升了疾病检测的准确度以及效率。深度学习模型可以分析X光图、核磁共振图像以及CT扫描图像来识别异常情况。这种技术为放射科医生提供支持并且让医生能尽早接入疑似癌症的症状。
人工智能和机器人技术的结合创造了先进的自动系统。这些系统将人工智能的决策指定能力和机器人的物理交互能力相结合。其应用场景包括家庭服务机器人、工业自动化机器人和太空探索机器人。
人工智能的训练数据质量直接影响模型的表现。高质量的数据应该是准确、多样并且有代表性的。数据清洗以及标注过程对于移除偏差以及确保模型在真实世界中生成良好内容是至关重要的。