2021杭电多校第十场 1003 Pty loves lines

一条一条的往上加 可以发现 问题就是问m组(组内直线两两平行)的直线能行成多少个交点
思路:dfs
一组一组的往里面放 放完当前组后 把剩余的所有看成一组 计算其总价值
如果此价值之前出现过 则不继续dfs [1]
价值计算公式:
已放入的直线的价值v + 该组放入后的价值(i*x) + 剩余的产生的价值 (n-1-x+*(x+i)
其中:i是当前组放入的直线的数量 x是已放入直线的数量

[1] emmm大家自己领悟一下 我也说不明白 对不起 我是菜比

#include <bits/stdc++.h>
#define pb push_back
#define xx first
#define yy second
#define in(x) scanf("%d",&x)
#define lin(x) scanf("%lld",&x)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 3e5+10;
const int M = N*2;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-7;
const double PI = acos(-1);
ll qpow(ll a,ll b){ll res = 1;while(b){if(b&1)  res = res*a%MOD;a = a*a%MOD;b >>= 1;}return res;}
int n,m,k;
bool st[N];
void dfs(int x,int v){
    for(int i = 1;i <= n-x;i++){
        int tp = v+i*x+(n-i-x)*(x+i);   // 前 中 后三个部分
        if(!st[tp]){    // 关键
            st[tp] = 1;
            dfs(x+i,v+i*x);
        }

    }
}
vector <int> ans;
signed main(){
#ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
#endif
    int T;  in(T);
    while(T--){
        in(n);
        memset(st,0,sizeof st);
        ans.clear();
        dfs(0,0);
        for(int i = 0;i < N;i++)    // 跑了一下700最多能到25e4 所以直接开3e5的数组保存
            if(st[i])   ans.pb(i);

        for(int i = 0;i < ans.size();i++)
            printf("%d%c",ans[i]," \n"[i==ans.size()-1]);
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容