问题 J: 位置2016
题目描述
由于晨晨还没有研究出核心算法,在游戏中总是被明明击败。晨晨拿出了杀手锏进行反击,精心设计了一个数学难题:
N个地砖,每个上面写有一个编号,开始这些编号从左到右正好是1到N。例如N=20时,地砖摆放如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
晨晨对其中哪些位置上的编号是回文数感兴趣,不过这个问题不足以击败明明,比如上面的N=20,明明很容易就给出答案:
1 2 3 4 5 6 7 8 9 11
晨晨为了干扰明明,疯狂地进行了M次操作,每次操作如下:
给定2个整数a和b (1 ≤ a ≤ b ≤N),晨晨把位置a到b的这段地砖的编号左右“翻转”一下。
比如对于N=20,M=2。执行一次a=3, b=15的操作,地砖编号变为:
1 2 15 14 13 12 11 10 9 8 7 6 5 4 3 16 17 18 19 20
再执行一次a=1, b=4的操作,地砖编号变为:
14 15 2 1 13 12 11 10 9 8 7 6 5 4 3 16 17 18 19 20
如果这个时候晨晨再问明明回文数的位置,明明就要给出答案:
3 4 7 9 10 11 12 13 14 15
输入
第一行:2个正整数N,M。N的范围为[1, 1000000],M的范围为[1, 1000]。
下面M行:每行2个整数a和b(1 ≤ a ≤ b ≤N)。
输出
一行整数,表示所有编号为回文数的地砖的位置。
样例输入 Copy
100 3
5 20
1 100
10 90
样例输出 Copy
2 13 15 16 17 18 19 21 32 43 54 65 76 87 97 98 99 100
这场唯一一个没AC的题,你以为它难吗,不,它只是一道水题,我输在了自己的花里胡哨。
普通的交换两个数字不用,偏偏用了位运算符。
ll temp=a[t1+i];
a[t1+i]=a[t2-i];
a[t2-i]=temp;
你看它多朴素。
a[t1+i]^=a[t2-i]^=a[t1+i]^=a[t2-i];
你看它多花里胡哨。可偏偏只因这个超时(其他全对的),我枯了。。。
不说了,码上。
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[1000005],n,m,x,y;
void change(ll t1,ll t2){
//倒置
ll mid=(t2-t1)/2;
for(ll i=0;i<=mid;i++){
ll temp=a[t1+i];
a[t1+i]=a[t2-i];
a[t2-i]=temp;
}
// a[t1+i]^=a[t2-i]^=a[t1+i]^=a[t2-i];
}
bool f(ll n){
//回文数判断
ll temp=n;
ll cot=0;
while(temp){
cot=cot*10+temp%10;
temp/=10;
}
if(cot==n) return 1;
else return 0;
}
int main(){
cin>>n>>m;
for(ll i=1;i<=n;i++) a[i]=i;
while(m--){
cin>>x>>y;
change(x,y);
}
for(ll i=1;i<=n;i++){
if(f(a[i])) printf("%lld ",i);
}
}