今天打得还算顺利,这题有坑,写一下吧,由于wcr小朋友凭借他聪明的小脑袋先开了这题,,导致后面许多队不幸掉坑,题意大概就是一个键盘一样的东西,你每次只能往下或者往右挪动手去按数字,一个数字可以按多次,给定一个数字n,求能按到的距离n最近的数字,这题主要就是坑在,如果距离相当,在取数字的时候,是没有上界的,虽然给出的数字是到两百,但是按的数字可以大于两百。
这题本来我想打表,从每个数字出发搜索一下能到达的数字然后进行标记,wwz同学机智的想到用一个二维数组vis,vis[i][j]表示数字i是否能排在j前面,然后就是从给定的数字开始往左右两侧搜索是否能按,对于每个数字,判断它的相邻两位是否满足条件,就可以了。
<span style="font-size:18px;">#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<list>
#include<cmath>
#include<set>
#include<queue>
using namespace std;
typedef long long ll;
const int INF = 100000000;
const long long maxn = 111;
int T,n,m,k,vis[20][20];
void init() {
memset(vis,-1,sizeof(vis));
for(int i=1;i<=9;i++) {
for(int j=1;j<i;j++) vis[i][j] = 0;
if(i == 1 || i == 4 || i == 7) continue;
else if(i == 2 || i == 5 || i == 8) {
vis[i][1] = vis[i][4] = vis[i][7] = 0;
}
else {
vis[i][1] = vis[i][4] = vis[i][7] = vis[i][2] = vis[i][5] = vis[i][8] = 0;
}
}
vis[3][0] = vis[6][0] = vis[9][0] = 0;
for(int i=1;i<=9;i++) vis[0][i] = 0;
}
int main() {
scanf("%d",&T);
init();
while(T--){
scanf("%d",&k);
bool ok = false;
int ans = 0;
for(int i=0;i<=k;i++) {
int v1 = k - i , v2 = k + i;
if(v2 <= 200) {
if(v2<10) { ok = true; ans = v2; break; }
else if(v2 < 100) { if(vis[v2/10][v2%10]) { ans = v2; break; } }
else { if(vis[v2/100][(v2-v2/100*100)/10]&&vis[(v2-v2/100*100)/10][v2%10]) {ans = v2; break;} }
}
if(v1 >= 0) {
if(v1<10) { ok = true; ans = v1; break; }
else if(v1 < 100) { if(vis[v1/10][v1%10]) { ans = v1; break; } }
else { if(vis[v1/100][(v1-v1/100*100)/10]&&vis[(v1-v1/100*100)/10][v1%10]) {ans = v1; break;} }
}
}
printf("%d\n",ans);
}
return 0;
}</span>
还有一个人用的做法就是我说的那样,先搜索一下,把能到达的数字放到数组里,然后lower_bound就可以了。
<span style="font-size:18px;">#include <iostream>
#include <set>
using namespace std;
set<int> s;
set<int>::iterator p;
void dfs(int m, int n, int d) {
if(m < 201)
s.insert(m);
else return;
if(n == 11)
n = 0;
if(d == 3 || n > 9 )
return;
dfs(m * 10 + n, n, d + 1);
if(n % 3)
dfs(m, n + 1, d);
if(n)
dfs(m, n + 3, d);
}
int main() {
int t, n, m;
dfs(0, 1, 0);
// for(p = s.begin(); p != s.end(); p++)
// cout << *p << endl;
cin >> t;
while(t--) {
cin >> n;
p = s.lower_bound(n);
m = *p;
if(p != s.begin()) {
p--;
if(n - *p < m - n)
m = *p;
}
cout << m << endl;
}
return 0;
}</span>