codeforces 1469D
题意:
给定1~n的序列,可以任意选取x和y,使得x=ceil(x/y),问不超过n+5次使序列变成n-1个1和一个2
思路1:
首先1和2可以不用变,3到n-1都可以变成1,然后处理n,发现要处理log(n)次,显然数据大的话不满足条件,可以考虑找一个数字让n变成1,然后让这个数字通过2再变成1,可以写个程序测试发现,n=200000的时候最多需要9次,正好加上n-4之后就是n+5,满足条件
题解1:
#include <bits/stdc++.h>
#define eb emplace_back
#define divUp(a,b) (a+b-1)/b
#define mkp(x,y) make_pair(x,y)
#define all(v) begin(v),end(v)
#define int long long
#define deb(x) cout<<#x<<" "<<x<<endl;
using namespace std;
typedef unsigned long long ull;
typedef pair<int, int> pii;
bool checkP2(int n) {return n > 0 and (n & (n - 1)) == 0;};
template<typename... T>
void read(T&... args) {
((cin >> args), ...);
}
template<typename... T>
void put(T... args) {
((cout << args << " "), ...);
cout<<endl;
}
int test(int a, int b) {
int cnt = 0;
while (a > 1) {
a = (a + b - 1) / b;
cnt++;
}
return cnt;
}
void solve() {
int n;
read(n);
vector<pii> v;
int times = n - 3;
int p = -1;
int mmin = 1e9;
if(n==3){
cout<<2<<endl;
put(3,2);
put(3,2);
return;
}
for (int i = 3; i < n; i++) {
if (mmin > test(i, 2) + test(n, i)) {
mmin = test(i, 2) + test(n, i);
p = i;
}
}
for (int i = 3; i < n; i++) {
if (i == p) continue;
v.eb(mkp(i, n));
}
int cur = n,i=p;
while (cur > 1) {
v.eb(mkp(n, i));
cur = (cur + i - 1) / i;
}
while (p > 1) {
v.eb(mkp(i, 2));
p = (p + 1) / 2;
}
cout<<v.size()<<endl;
for(auto [x,y]:v){
put(x,y);
}
}
signed main() {
ios::sync_with_stdio(false); cin.tie(0);
int _; cin >> _; while (_--)
solve();
return 0;
}
思路2:
要处理n的话可以使用sqrt(n)通过两次就可以变成1,然后依次处理剩下的sqrt,可以发现sqrt(200000)只要5次,也就是一共n+5次,感觉这个像是正解。。。
题解:
#include <bits/stdc++.h>
#define eb emplace_back
#define divUp(a,b) (a+b-1)/b
#define mkp(x,y) make_pair(x,y)
#define all(v) begin(v),end(v)
#define int long long
#define deb(x) cout<<#x<<" "<<x<<endl;
using namespace std;
typedef unsigned long long ull;
typedef pair<int, int> pii;
bool checkP2(int n) {return n > 0 and (n & (n - 1)) == 0;};
template<typename... T>
void read(T&... args) {
((cin >> args), ...);
}
template<typename... T>
void put(T... args) {
((cout << args << " "), ...);
cout << endl;
}
bool st[200010];
void solve() {
int n;
read(n);
for (int i = 1; i <= n; i++) st[i] = false;
int cur = n;
st[cur] = true;
int cnt = 0;
vector<int> v;
v.eb(cur);
while (cur > 2) {
int tem = ceil(sqrt(cur));
cur = tem;
st[cur] = true;
v.eb(cur);
}
vector<pii> res;
for (int i = 3; i < n; i++) {
if (!st[i]) res.eb(mkp(i, n));
}
sort(all(v), greater<int>());
for (int i = 0; i < v.size() - 1; i++) {
res.eb(mkp(v[i], v[i + 1]));
res.eb(mkp(v[i], v[i + 1]));
}
put(res.size());
for (auto [x, y] : res) {
put(x, y);
}
}
signed main() {
ios::sync_with_stdio(false); cin.tie(0);
int _; cin >> _; while (_--)
solve();
return 0;
}