• Tokio Marine & Nichido Fire Insurance Programming Contest 2021 (AtCoder Regular Contest 122)


    (sf B-Insurance)

    题目

    传送门

    解法

    感觉自己的做法还蛮特别的,就来写一写。虽然并不优。

    首先将算式转化成:

    [sum_{i=1}^n A_i+minleft { sum_{i=1}^n max{x-A_i,-x} ight } ]

    我们发现,后面 (max) 的取值和 (2x)(A_i) 的关系有关,于是我们排个序枚举分界点,这样前一半是 (x-A_i) 后一半是 (-x) 就可以快速计算了。

    最后再判断一下取 (A_{i}/2)(A_{i+1}/2) 哪个结果小就行了。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    #define rep(i,_l,_r) for(register signed i=(_l),_end=(_r);i<=_end;++i)
    #define fep(i,_l,_r) for(signed i=(_l),_end=(_r);i>=_end;--i)
    #define erep(i,u) for(signed i=head[u],v=to[i];i;i=nxt[i],v=to[i])
    #define efep(i,u) for(signed i=Head[u],v=to[i];i;i=nxt[i],v=to[i])
    #define print(x,y) write(x),putchar(y) 
    #define debug(...) do {cerr<<__LINE__<<" : ("#__VA_ARGS__<<") = "; Out(__VA_ARGS__); cerr<<flush;} while(0)
    template <typename T> void Out(T x) {cerr<<x<<"
    ";}
    template <typename T,typename ...I> void Out(T x,I ...NEXT) {cerr<<x<<", "; Out(NEXT...);}
    
    template <class T> inline T read(const T sample) {
        T x=0; int f=1; char s;
        while((s=getchar())>'9'||s<'0') if(s=='-') f=-1;
        while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
        return x*f;
    }
    template <class T> inline void write(const T x) {
        if(x<0) return (void) (putchar('-'),write(-x));
        if(x>9) write(x/10);
        putchar(x%10^48);
    }
    template <class T> inline T Max(const T x,const T y) {if(x>y) return x; return y;}
    template <class T> inline T Min(const T x,const T y) {if(x<y) return x; return y;}
    template <class T> inline T fab(const T x) {return x>0?x:-x;}
    template <class T> inline T gcd(const T x,const T y) {return y?gcd(y,x%y):x;}
    template <class T> inline T lcm(const T x,const T y) {return x/gcd(x,y)*y;}
    
    const int maxn=1e5+5;
    
    int n;
    double a[maxn],sum,ans;
    
    int main() {
    	n=read(9);
    	rep(i,1,n) a[i]=read(9);
    	sort(a+1,a+n+1);
    	rep(i,1,n+1) {
    		double x,tmp=i-1-(n-i+1);
    		if(tmp>0) x=a[i-1]/2;
    		else x=a[i]/2;
    		ans=Min(ans,tmp*x-sum);
    		sum+=a[i];
    	}
    	printf("%.10f
    ",(ans+sum)/n);
    	return 0;
    }
    

    (sf C-Calculator)

    题目

    传送门

    解法

    手玩就能发现,这其实就是将 (n) 拆分成几个斐波那契数。

    可以证明,任意正整数 (n) 可以被拆分成互异的斐波那契数。又因为如果选择了 ( ext{fib}_i, ext{fib}_{i+1}) 肯定就会换成 ( ext{fib}_{i+2}),所以我们不会选择连续的斐波那契数。而数据范围中斐波那契数最多到 (87) 项(( ext{fib}_1= ext{fib}_{2}=1)),所以如果我们都选奇数项就有 (44) 项。不过事实上这个上界达不到,因为 ( ext{fib}_{87}+ ext{fib}_{85}+ ext{fib}_{83}>10^{18})

    构造就是边加入 (1),边用 (3,4) 操作拓展斐波那契数列,(3,4) 操作的上界是 (86)

    所以总体上界为 (130),足以通过此题。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    #define rep(i,_l,_r) for(register signed i=(_l),_end=(_r);i<=_end;++i)
    #define fep(i,_l,_r) for(signed i=(_l),_end=(_r);i>=_end;--i)
    #define erep(i,u) for(signed i=head[u],v=to[i];i;i=nxt[i],v=to[i])
    #define efep(i,u) for(signed i=Head[u],v=to[i];i;i=nxt[i],v=to[i])
    #define print(x,y) write(x),putchar(y) 
    #define debug(...) do {cerr<<__LINE__<<" : ("#__VA_ARGS__<<") = "; Out(__VA_ARGS__); cerr<<flush;} while(0)
    template <typename T> void Out(T x) {cerr<<x<<"
    ";}
    template <typename T,typename ...I> void Out(T x,I ...NEXT) {cerr<<x<<", "; Out(NEXT...);}
    
    template <class T> inline T read(const T sample) {
        T x=0; int f=1; char s;
        while((s=getchar())>'9'||s<'0') if(s=='-') f=-1;
        while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
        return x*f;
    }
    template <class T> inline void write(const T x) {
        if(x<0) return (void) (putchar('-'),write(-x));
        if(x>9) write(x/10);
        putchar(x%10^48);
    }
    template <class T> inline T Max(const T x,const T y) {if(x>y) return x; return y;}
    template <class T> inline T Min(const T x,const T y) {if(x<y) return x; return y;}
    template <class T> inline T fab(const T x) {return x>0?x:-x;}
    template <class T> inline T gcd(const T x,const T y) {return y?gcd(y,x%y):x;}
    template <class T> inline T lcm(const T x,const T y) {return x/gcd(x,y)*y;}
    
    typedef long long ll;
    
    ll n,f[100];
    int sta[100],tp,ans[200],len,fuck;
    
    void init() {
    	f[1]=f[2]=1;
    	rep(i,3,90) f[i]=f[i-1]+f[i-2];
    }
    
    int main() {
    	init();
    	n=read(9ll);
    	fep(i,90,1) if(n>=f[i]) sta[++tp]=i,n-=f[i];
    	fep(i,tp,1)
    		if(sta[i]&1) {
    			while(fuck<sta[i]-1) {
    				if(fuck&1) ans[++len]=4;
    				else ans[++len]=3;
    				++fuck;
    			}
    			ans[++len]=1;
    		}
    		else {
    			while(fuck<sta[i]-1) {
    				if(fuck&1) ans[++len]=4;
    				else ans[++len]=3;
    				++fuck;
    			}
    			ans[++len]=2;
    		}
    	print(len,'
    ');
    	fep(i,len,1) print(ans[i],'
    ');
    	return 0;
    }
    

    (sf E-Increasing LCMs)

    题目

    传送门

    解法

    我们考虑 (a_n) 满足的条件:将所有数质因数分解,(a_n) 分解后某质数 (p) 的幂次大于 ([1,n-1]) 中任意一个数 (p) 的幂次。

    那我们每次找到可以作为末尾的数,然后从后往前填。

    考虑贪心的正确性。首先肯定是越填限制越松的。对于同一状态下都可以填的两个数 (i,j),显然使它们可以作为末尾的质因子互异,所以它们的先后顺序是可以随便定的。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    #define rep(i,_l,_r) for(register signed i=(_l),_end=(_r);i<=_end;++i)
    #define fep(i,_l,_r) for(signed i=(_l),_end=(_r);i>=_end;--i)
    #define erep(i,u) for(signed i=head[u],v=to[i];i;i=nxt[i],v=to[i])
    #define efep(i,u) for(signed i=Head[u],v=to[i];i;i=nxt[i],v=to[i])
    #define print(x,y) write(x),putchar(y) 
    #define debug(...) do {cerr<<__LINE__<<" : ("#__VA_ARGS__<<") = "; Out(__VA_ARGS__); cerr<<flush;} while(0)
    template <typename T> void Out(T x) {cerr<<x<<"
    ";}
    template <typename T,typename ...I> void Out(T x,I ...NEXT) {cerr<<x<<", "; Out(NEXT...);}
    
    template <class T> inline T read(const T sample) {
        T x=0; int f=1; char s;
        while((s=getchar())>'9'||s<'0') if(s=='-') f=-1;
        while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
        return x*f;
    }
    template <class T> inline void write(const T x) {
        if(x<0) return (void) (putchar('-'),write(-x));
        if(x>9) write(x/10);
        putchar(x%10^48);
    }
    template <class T> inline T Max(const T x,const T y) {if(x>y) return x; return y;}
    template <class T> inline T Min(const T x,const T y) {if(x<y) return x; return y;}
    template <class T> inline T fab(const T x) {return x>0?x:-x;}
    template <class T> inline T gcd(const T x,const T y) {return y?gcd(y,x%y):x;}
    template <class T> inline T lcm(const T x,const T y) {return x/gcd(x,y)*y;}
    
    typedef long long ll;
    
    const int maxn=105;
    
    int n,id[maxn];
    ll a[maxn],g[maxn][maxn];
    
    int main() {
    	n=read(9);
    	rep(i,1,n) a[i]=read(9ll),id[i]=i;
    	rep(i,1,n) rep(j,1,n) g[i][j]=gcd(a[i],a[j]);
    	fep(i,n,1) {
    		bool flag=false;
    		rep(j,1,i) {
    			ll tmp=1;
    			rep(k,1,i) if(j^k) tmp=lcm(tmp,g[id[j]][id[k]]);
    			if(tmp^a[id[j]]) {
    				rep(k,j,i-1) swap(id[k],id[k+1]);
    				flag=true; break;
    			}
    		}
    		if(!flag) return puts("No"),0;
    	}
    	puts("Yes");
    	rep(i,1,n) print(a[id[i]],' '); puts("");
    	return 0;
    }
    
  • 相关阅读:
    批量数据导入数据库方法
    Remoting简单实践
    js面向对象继承
    Linq实现t-Sql的各种连接
    数据库树状结构的关系表的删除方案
    记录一次SQL查询语句
    mvc请求过程总结
    T-sql表表达式
    各个浏览器的兼容问题及样式兼容处理(不定期补充)
    vue.js 键盘enter事件的使用
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/14887586.html
Copyright © 2020-2023  润新知