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;
}
posted @ 2021-10-21 22:32  指引盗寇入太行  阅读(32)  评论(0编辑  收藏  举报