C.有向无环图(构造 / 特定路径数的有向图) (智算之道复赛高校组)

传送门

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
思路: 个人觉得应该要用到前缀和。

骗分代码(60分):

#include<bits/stdc++.h>
#define endl '\n'
#define null NULL
#define ll long long
#define int long long
#define pii pair<int, int>
#define lowbit(x) (x &(-x))
#define ls(x) x<<1
#define rs(x) (x<<1+1)
#define me(ar) memset(ar, 0, sizeof ar)
#define mem(ar,num) memset(ar, num, sizeof ar)
#define rp(i, n) for(int i = 0, i < n; i ++)
#define rep(i, a, n) for(int i = a; i <= n; i ++)
#define pre(i, n, a) for(int i = n; i >= a; i --)
#define IOS ios::sync_with_stdio(0); cin.tie(0);cout.tie(0);
const int way[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
using namespace std;
const int  inf = 0x7fffffff;
const double PI = acos(-1.0);
const double eps = 1e-6;
const ll   mod = 1e9 + 7;
const int  N = 2e5 + 5;

int n, k;
vector<int> v[1000];

signed main(){
	IOS;
	cin >> k >> n;
	if(k == 1) cout << "2 1" << endl << "1 2" << endl;
    else if(k == 2) cout << "3 3" << endl << "1 2" << endl << "1 3" << endl << "2 3" << endl;
    else if(k == 3) cout << "4 5" << endl << "1 2" << endl << "1 3" << endl << "2 3" << endl << "1 4" << endl << "3 4" << endl;
	else{
	int n1=0,m=0;
	bool flag=0;
	int cnt=0;
	for(int i=1;i<=k;i++) v[i].push_back(n);
	for(int i=1;i<=n;i++){
		n1=i;
		for(int j=i+1;j<=n;j++){
			if(cnt==k) continue;
			m++;
			v[i].push_back(j);
			if(m==k) flag=1;
			if(flag) break;
		}
		if(flag) break;
	}
	cout<<n<<" "<<m+k<<endl;
	for(int i=1;i<=max(n1,k);i++){
		for(int j=0;j<v[i].size();j++){
			cout<<i<<" "<<v[i][j]<<endl;}
		}
	}
    return 0;
}

学姐AC代码:

#include<bits/stdc++.h>
#define endl '\n'
#define null NULL
#define ll long long
#define int long long
#define pii pair<int, int>
#define lowbit(x) (x &(-x))
#define ls(x) x<<1
#define rs(x) (x<<1+1)
#define me(ar) memset(ar, 0, sizeof ar)
#define mem(ar,num) memset(ar, num, sizeof ar)
#define rp(i, n) for(int i = 0, i < n; i ++)
#define rep(i, a, n) for(int i = a; i <= n; i ++)
#define pre(i, n, a) for(int i = n; i >= a; i --)
#define IOS ios::sync_with_stdio(0); cin.tie(0);cout.tie(0);
const int way[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
using namespace std;
const int  inf = 0x7fffffff;
const double PI = acos(-1.0);
const double eps = 1e-6;
const ll   mod = 1e9 + 7;
const int  N = 2e5 + 5;

unsigned long long k, n, a[70] = {0};

struct node{
    int u, v;
};
vector<node> ans;

void solve(){
    int s = 1,t = 2;
        a[2] = 1;
        ans.push_back({s,t});
        int tmp = 2;k-=1;
        while(k){
            tmp ++;
            ans.push_back({s, tmp});
            unsigned long long tmp1 = 0;
            for(int i = tmp-1; k>0 && i>=2 ; i --){
                if(k >= a[i]){
                    ans.push_back({tmp, i});
                    k -= a[i];
                    tmp1 += a[i];
                }
            }
            a[tmp] = tmp1;
        }
        cout << tmp << " " << (int)ans.size() << endl;
        int l=(int)ans.size();
        for(int i=0; i<l; i++) printf("%d %d\n", (ans[i].u == 1 ? 1 : tmp - ans[i].u + 2), tmp - ans[i].v + 2);
}

signed main()
{
    cin >> k >> n;
   	if(k == 1) cout << "2 1" << endl << "1 2" << endl;
    else if(k == 2) cout << "3 3" << endl << "1 2" << endl << "1 3" << endl << "2 3" << endl;
    else if(k == 3) cout << "4 5" << endl << "1 2" << endl << "1 3" << endl << "2 3" << endl << "1 4" << endl << "3 4" << endl;
    else solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Satur9/article/details/107901737