zoukankan      html  css  js  c++  java
  • 20210810贪心模拟赛

    还是开始写的很晚……因为调题速度比较慢……

    赛时

    约20分钟看全四道题目。

    其实都没有太好的思路,

    T4

    认为(T4)的暴力(50pts)很好拿,先用了约(0.5h)写了(T4)(50pts).另50分没有太想好

    (赛后:写的暴力数据范围小了导致(50 o20)……

    现在+机房大佬的(T4),有如下:

    CF1416C XOR Inverse

    把所有数字按01串存放到01trie中。

    考虑如何产生逆序对:
    后加的数如果比trie里已有的数大的话,必定产生逆序对。
    且:当且仅当某两个数字,他们的前缀完全相同,在第i位处01串不同,且后入的数是1,前入的数是0.

    可以发现对于每一位的操作是独立的.

    因为题里要求异或结果,若某一位的数字因异或而发生改变,则原本的逆序对变成现在的正序对,同理原本的正序对变成现在的逆序对(指每个节点下存储的正逆序对个数).

    于是问题转化为维护其正序对和逆序对,选取答案最小即可。

    #include <bits/stdc++.h>
    #define fo(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
    using namespace std;
    const int INF = 0x3f3f3f3f , N = 4e6+5;
    typedef long long ll;
    typedef unsigned long long ull;
    inline ll read(){
    	ll ret = 0 ; char ch = ' ' , c = getchar();
    	while(!(c >= '0' && c <= '9'))ch = c , c = getchar();
    	while(c >= '0' && c <= '9')ret = (ret << 1) + (ret << 3) + c - '0' , c = getchar();
    	return ch == '-' ? -ret : ret;
    }
    int n;
    int trie[N][2],tot = 1;
    ll ans[35][2],siz[N];
    int a[35];
    void insert(int x){
    	for(int i = 30 ; i >= 0 ; i --)
    		a[i] = !!(x & (1<<i));
    //	for(int i = 17 ; i >= 0 ; i --)printf("%d",a[i]);puts("");
    	int p = 1;
    	for(int i = 30 ; i >= 0 ; i --){
    		if(a[i]) ans[i][1] += siz[trie[p][0]];
    		else ans[i][0] += siz[trie[p][1]];
    		
    		if(!trie[p][a[i]]) trie[p][a[i]] = ++tot;
    		p = trie[p][a[i]];
    		siz[p] ++;
    	}
    }
    signed main(){
    	fo("inverse");
    	n = read();
    	while(n --){
    		int x = read();
    		insert(x);
    	}
    	ll Ans = 0 ;int pos = 0;
    	for(int i = 0 ; i <= 30 ; i ++)
    		if(ans[i][0] <= ans[i][1])
    			Ans += ans[i][0];
    		else Ans += ans[i][1],
    			pos += (1<<i);
    	printf("%lld %d
    ",Ans,pos);
    			
    }
    

    T3

    然后想了(T3),想到了类似于正解的做法,但是还是缺少细节……

    UVA1747 Swap Space

    按照“格式化后增大的升序,格式化后减小的降序”排序处理即可。

    #include <bits/stdc++.h>
    #define fo(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
    using namespace std;
    const int INF = 0x3f3f3f3f , N = 1e6+5;
    typedef long long ll;
    typedef unsigned long long ull;
    inline ll read(){
    	ll ret = 0 ; char ch = ' ' , c = getchar();
    	while(!(c >= '0' && c <= '9'))ch = c , c = getchar();
    	while(c >= '0' && c <= '9')ret = (ret << 1) + (ret << 3) + c - '0' , c = getchar();
    	return ch == '-' ? -ret : ret;
    }
    int n;
    struct node{int a,b;}a1[N],a2[N];
    inline bool cmp1 (const node& a,const node& b){
    	return a.a < b.a;
    }
    inline bool cmp2 (const node& a,const node& b){
    	return a.b > b.b;
    }
    int cnt1,cnt2;
    ll ans,emp;
    signed main(){
    	n = read();
    	for(int i = 1 ; i <= n ; i ++){
    		int a = read() , b = read();
    		if(a <= b)
    			a1[++cnt1] = (node){a,b};
    		else a2[++cnt2] = (node){a,b};
    	}
    	sort(a1+1,a1+cnt1+1,cmp1);
    	sort(a2+1,a2+cnt2+1,cmp2);
    	for(int i = 1 ; i <= cnt1 ; i ++){
    		if(a1[i].a > emp)
    			ans += a1[i].a - emp , emp = a1[i].b;
    		else emp += a1[i].b - a1[i].a;
    //		printf("  (%d,%d) , %lld %lld
    ",a1[i].a,a1[i].b,ans,emp);
    	}
    	for(int i = 1 ; i <= cnt2 ; i ++){
    		if(a2[i].a > emp)
    			ans += a2[i].a - emp , emp = a2[i].b;
    		else emp += a2[i].b - a2[i].a;
    	}
    	printf("%lld",ans);
    }
    

    T2、T1

    上面两道题比较有把握,但是都没有拿到如愿的分数……

    (T2、T1)两道题的贪心策略就基本没有找好……导致几乎爆零……

    现在看看,两道题其实都是水题……

    (T2)正解:状压DP.

    (T1)正解:纯贪心+暴力.

    赛后

    名为贪心模拟赛,问题在于没有想到很好的贪心策略。这与平时做题数量和质量是有关的。下一步要着重加强这一部分。

  • 相关阅读:
    跨媒体安全
    kali视频(21-25)学习
    kali视频(26-30)学习
    kali视频(16-20)学习
    kali视频学习(11-15)
    kali视频(1-5)
    使用Metaspoit攻击MS08-067
    web应用程序安全攻防---sql注入和xss跨站脚本攻击
    -区块链-
    TCP/IP网络协议攻击
  • 原文地址:https://www.cnblogs.com/Shinomiya/p/15126475.html
Copyright © 2011-2022 走看看