给出两个整数 A A A和 B B B,找出一个非负整数 C C C使得 A ⊕ C = B A\oplus C=B A⊕C=B。
因为异或是自反的,所以 C = A ⊕ B C=A\oplus B C=A⊕B。
#include
using namespace std;
int a,b;
int main()
{
cin>>a>>b;
cout<<(a^b)<<endl;
return 0;
}
给出 n n n个不同的整数,问第二大的整数的第几个整数。
每个整数带上序号排序即可。
#include
using namespace std;
const int N=2e5+10;
struct Node{
int id,sc;
}a[N];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].sc;
a[i].id=i;
}
sort(a+1,a+1+n,[&](Node a,Node b){
return a.sc>b.sc;
});
cout<<a[2].id<<endl;
return 0;
}
有一个 H × W H\times W H×W的矩阵,有 N N N个位置上分别写有数字,第 i i i个数字写在第 A i A_i Ai行第 B i B_i Bi列。
会将所有不存在数字的行和列全部删去,问最后这 N N N个数字的下标是多少。
因为所有不存在数字的行和列都会被删去,所以留下来的一定是存在数字的行和列。
那么对行和列分别进行离散化,就能知道行和列在所有行列中的相对位置。
时间复杂度 O ( N l o g N ) O(NlogN) O(NlogN)
#include
using namespace std;
const int N=2e5+10;
struct Node{
int x,y;
}a[N];
int h,w,n;
int px[N],py[N];
vector<int> vx,vy;
int get(int x,vector<int> &v){
return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
int main()
{
scanf("%d%d%d",&h,&w,&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].x,&a[i].y);
vx.push_back(a[i].x);
vy.push_back(a[i].y);
}
sort(vx.begin(),vx.end());
vx.erase(unique(vx.begin(),vx.end()),vx.end());
sort(vy.begin(),vy.end());
vy.erase(unique(vy.begin(),vy.end()),vy.end());
for(int i=1;i<=n;i++) printf("%d %d\n",get(a[i].x,vx),get(a[i].y,vy));
return 0;
}
有 N N N座城市,所有城市之间有 N − 1 N-1 N−1条无向边。
现在从城市 1 1 1开始旅行:
输出旅行访问的城市顺序。
因为是一棵树,所以按照题意从点 1 1 1进行dfs就行了。
对于每个点按照从小到大的顺序进行深搜,因为每次都一定会回来,所以除了在要到达每个节点的时候输出一次当前节点,还要在dfs子节点结束之后输出当前节点。
#include
using namespace std;
const int N=2e5+10;
vector<int> e[N];
int n;
void dfs(int u,int pre){
printf("%d ",u);
bool flag=false;
for(int i=0;i<e[u].size();i++){
int j=e[u][i];
if(j==pre) continue;
dfs(j,u);
printf("%d ",u);
}
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n-1;i++){
int a,b;
scanf("%d%d",&a,&b);
e[b].push_back(a);
e[a].push_back(b);
}
for(int i=1;i<=n;i++) sort(e[i].begin(),e[i].end());
dfs(1,-1);
return 0;
}
给出一个 N × M N\times M N×M的平面,一部分格子是可以通过的,另一部分格子上面会有石头阻碍通过。
现在要从左上角走到右下角,因为主角身强体壮,可以一拳击碎 2 × 2 2\times2 2×2的区域内的所有石头,问最少需要打拳几次才能走到右下角。
如果我们在BFS的过程中,遇到了走不通的情况,在把某个石头作为要击穿的对象,那么这个以这个石头为中心的 3 × 3 3\times 3 3×3区域内的所有格子我们都能花费 1 1 1次的代价走到。
所以整张图就变成了边权只有 0 0 0和 1 1 1的情况,可以考虑用双端队列来进行BFS。
边权为0的就加入到队头,边权为1的就加入到队尾。
时间复杂度 O ( N ∗ M ) O(N*M) O(N∗M)。
#include
using namespace std;
typedef pair<int,int> PII;
const int N=510;
int g[N][N];
int n,m;
int nxt[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int dist[N][N];
bool vis[N][N];
int bfs()
{
memset(dist,0x3f,sizeof dist);
deque<PII> que;
que.push_front({1,1});
dist[1][1]=0;
while(!que.empty()){
PII t=que.front();
que.pop_front();
int x=t.first,y=t.second;
if(vis[x][y]) continue;
vis[x][y]=true;
for(int i=0;i<4;i++){
int tx=x+nxt[i][0];
int ty=y+nxt[i][1];
if(tx<=0||tx>n||ty<=0||ty>m||dist[tx][ty]<=dist[x][y]) continue;
if(!g[tx][ty]){
dist[tx][ty]=dist[x][y];
que.push_front({tx,ty});
}
else{
for(int j=-1;j<=1;j++){
for(int k=-1;k<=1;k++){
int dx=tx+j;
int dy=ty+k;
if(dx<=0||dx>n||dy<=0||dy>m||dist[dx][dy]<=dist[x][y]+1) continue;
dist[dx][dy]=dist[x][y]+1;
que.push_back({dx,dy});
}
}
}
}
}
return dist[n][m];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
char s[N];
scanf("%s",s+1);
for(int j=1;j<=m;j++) g[i][j]=(s[j]=='.'?0:1);
}
printf("%d\n",bfs());
return 0;
}