题目链接:点击打开链接
题意:
输出n l x y
有一根直尺长度为l
上面有n个刻度。
以下n个数字是距离开头的长度(保证第一个数字是0,最后一个数字是l)
要使得 直尺中存在某2个刻度的距离为x 。 某2个刻度的距离为y
要加入最少几个刻度。
问:
最少的刻度个数
输出标记的位置。
思路:
分类讨论一下。。
若本身尺子里就有x、y就输出0
若仅仅有x 或仅仅有y就输出一个刻度。
若2个都没有就:
1、加1个刻度ans。这个ans是距离某个刻度距离为x的,然后看一下是否有距离ans为y的刻度,若有则加入一个ans就可以。
2、第1个都非法时就直接加2个刻度。
<pre name="code" class="cpp">#include <cstdio> #include <iostream> #include <cstring> #include <queue> #include <algorithm> #include <map> #include <cmath> template <class T> inline bool rd(T &ret) { char c; int sgn; if(c=getchar(),c==EOF) return 0; while(c!='-'&&(c<'0'||c>'9')) c=getchar(); sgn=(c=='-')?-1:1; ret=(c=='-')?0:(c-'0'); while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0'); ret*=sgn; return 1; } template <class T> inline void pt(T x) { if (x <0) { putchar('-'); x = -x; } if(x>9) pt(x/10); putchar(x%10+'0'); } using namespace std; typedef long long ll; const int N = 200050; vector<ll>G; bool Find(ll x){ for(int i = G.size()-2; i > 0; i--) { if(G[i] - x < 0)return false; if( G[lower_bound(G.begin(), G.end(), G[i] - x) - G.begin()] == G[i] - x) return true; } return false; } ll n, l, x, y; ll go(){ ll ans; for(int i = G.size()-2; i > 0; i--){ ans = G[i]-x; if(ans >= 0 && ((ans+y<=l&&G[lower_bound(G.begin(), G.end(), ans+y) - G.begin()] == ans+y) || (ans-y>=0&&G[lower_bound(G.begin(), G.end(), ans-y) - G.begin()] == ans-y))) return ans; ans = G[i]+x; if(ans <= l && ((ans + y <= l && G[lower_bound(G.begin(), G.end(), ans+y) - G.begin()] == ans+y) || (ans-y>=0&&G[lower_bound(G.begin(), G.end(), ans-y) - G.begin()] == ans-y))) return ans; } return -1; } void input(){ G.clear(); G.push_back(-5000000001LL); ll tmp; while(n--){ rd(tmp); G.push_back(tmp); } G.push_back(1e10); } int main() { while(cin>>n>>l>>x>>y){ input(); int havx = Find(x), havy = Find(y); if(havx + havy == 2) puts("0"); else if(havx + havy == 1) { if(havx) printf("1 %I64d ", y); else printf("1 %I64d ", x); } else { ll ans = go(); if(ans == -1) { printf("2 %I64d %I64d ", x, y); } else printf("1 %I64d ", ans); } } return 0; }