zoukankan      html  css  js  c++  java
  • 2015 ICPC 长春

    A - Too Rich

    给定每一种面值的硬币的个数,求出用最多硬币表示出所给价值。
    倒着做可以用前缀和优化和剪枝。
    可以$O(1)$算出当前面值减去前缀和之后最少需要几个,然后在此基础上多做3次就可以了,因为前一种硬币最多3枚就可以表示后一种硬币了。

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    
    const int dx[] = {1, 1, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 2000};
    
    int a[20];
    int T, p;
    ll S[20];
    int ans;
    
    inline void upd(int &x, int y) {
    	if (y > x) x = y;
    }
    
    void dfs(int dep, ll val, int coins) {
    	//printf("%d %d %d
    ", dep, val, coins);
    	if (val < 0) {
    		return;
    	}
    	if (val == 0) {
    		upd(ans, coins);
    		return;
    	}
    	if (dep == 0) {
    		return;
    	}
    	int left = val - S[dep - 1];
    	if (left <= 0) {
    		dfs(dep - 1, val, coins);
    		if (a[dep] >= 1)
    			dfs(dep - 1, val - dx[dep], coins + 1);
    	} else {
    		int i = left / dx[dep];
    		if (left % dx[dep]) i++;
    		if (i <= a[dep])
    			dfs(dep - 1, val - i * dx[dep], coins + i);
    		else
    			dfs(dep - 1, val - a[dep]*dx[dep], coins + i);
    		i++;
    		if (i <= a[dep])
    			dfs(dep - 1, val - i * dx[dep], coins + i);
    		i++;
    		if (i <= a[dep])
    			dfs(dep - 1, val - i * dx[dep], coins + i);
    	}
    
    }
    int main() {
    	scanf("%d", &T);
    	while (T--) {
    		scanf("%d", &p);
    		for (int i = 1; i <= 10; i++)
    			scanf("%d", &a[i]);
    		for (int i = 1; i <= 10; i++)
    			S[i] = S[i - 1] + (ll)(a[i] * dx[i]);
    		ans = -1;
    		dfs(10, (ll)p, 0);
    		cout << ans << endl;
    	}
    	return 0;
    }
    

    B - Count a * b

    猜了一发结论$sum_{i|n} i^2 - sum_{i|n} 1$,结果是tle,卡了$O(Tsqrt(n))$的做法,加了枚举的优化。

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    
    const int N = 1e5;
    
    bool p[100005];
    int prime[100005],top;
    
    struct node{
    	int x,y;
    }ort[10005];
    
    void init(){
    	memset(p, 0, sizeof(p));
    	top = 0;
    	for (int i = 2; i <= N; ++i) {
    		if (!p[i]) {
    			prime[++top] = i;
    		}
    		for (int j = 1; j <= top; ++j) {
    			if (i * prime[j] > N)
    				break;
    			p[i * prime[j]] = 1;
    			if (i % prime[j] == 0)
    				break;
    		}
    	}
    }
    
    ull r1,r2;
    int ctop;
    
    void dfs(int dep,int now){
    	if(dep==ctop+1){
    		r1+=(ull)now*now;
    		return;
    	}
    	int t=1;
    	for(int i=0;i<=ort[dep].y;i++){
    		dfs(dep+1,now*t);
    		t*=ort[dep].x;
    	}
    }
    
    int main() {
    	//freopen("in.txt","r",stdin);
    	init();
    	int n, T;
    	cin >> T;
    	while (T--) {
    		scanf("%d", &n);
    		int tmp=n;
    		// ull res1 = 0, res2 = 0;
    		// for (int i = 1; i * i <= n; i++) {
    		// 	if (n % i == 0) {
    		// 		res1 += (ull)i * i;
    		// 		res2 ++;
    		// 		if (i * i != n) {
    		// 			int t = n / i;
    		// 			res1 += (ull)t * t;
    		// 			res2 ++;
    		// 		}
    		// 	}
    		// }
    		// res1 -= (ull)n * res2;
    		// printf("%llu
    ", res1);
    		ctop=0;
    		for(int i=1;i<=top && prime[i]*prime[i]<=n;i++){
    			if(n%prime[i]==0){
    				ctop++;
    				ort[ctop].x=prime[i];
    				ort[ctop].y=0;
    				while(n%prime[i]==0){
    					ort[ctop].y++;
    					n/=prime[i];
    				}
    			}
    		}
    		if(n!=1){
    			ctop++;
    			ort[ctop].x=n;
    			ort[ctop].y=1;
    		}
    		r1=0;r2=1;
    		for(int i=1;i<=ctop;i++)
    			r2=r2*(ull)(ort[i].y+1);
    		r2=r2*(ull)tmp;
    		dfs(1,1);
    		cout<<r1-r2<<endl;
    	}
    	return 0;
    }
    

    F - Almost Sorted Array

    判断是不是almost sorted array。
    跟着跑LIS,如果栈高比当前i小太多直接就是不对的了。
    所以复杂度还是$O(n)$。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 5;
    int T, n, k, a[maxn], k1, k2, ans[maxn], len, b[maxn], flag;
    template<typename T> inline void read(T &x){
    x=0;T f=1;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do x=x*10+ch-'0',ch=getchar();while(ch<='9'&&ch>='0');x*=f;
    }
    
    template<typename A,typename B> inline void read(A&x,B&y){read(x);read(y);}
    template<typename A,typename B,typename C> inline void read(A&x,B&y,C&z){read(x);read(y);read(z);}
    template<typename A,typename B,typename C,typename D> inline void read(A&x,B&y,C&z,D&w){read(x);read(y);read(z);read(w);}
    int main() {
    	//freopen("in.txt", "r", stdin);
    	read(T);
    	while (T--) {
    		flag = 0;
    		memset(ans, 0, sizeof(ans));
    		k1 = k2 = 0;
    		scanf("%d", &n);
    		for (int i = 1; i <= n; i++)
    			read(a[i]);
    		ans[1] = a[1];
    		len = 1;
    		for (int i = 2; i <= n; i++) {
    			if (a[i] >= ans[len])
    				ans[++len] = a[i];
    			else {
    				int pos = upper_bound(ans + 1, ans + len + 1, a[i]) - ans;
    				ans[pos] = a[i];
    			}
    			if(i-len>5) break;
    		}
    		if (len >= n - 1) {
    			puts("YES");
    			continue;
    		}
    		for (int i = 1; i <= n; i++)
    			b[i] = a[n - i + 1];
    		ans[1] = b[1];
    		len = 1;
    		for (int i = 2; i <= n; i++) {
    			if (b[i] >= ans[len])
    				ans[++len] = b[i];
    			else {
    				int pos = upper_bound(ans + 1, ans + len + 1, b[i]) - ans;
    				ans[pos] = b[i];
    			}
    			if(i-len>5) break;
    		}
    		if (len >= n - 1) puts("YES");
    		else puts("NO");
    	}
    	return 0;
    }
    

    G - Dancing Stars on Me

    每个点只有两个最近点,并且最近的距离相等。

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    
    double eps = 1e-8;
    
    inline int dcmp(double x) {
    	if (x > eps) return 1;
    	if (x < -eps) return -1;
    	return 0;
    }
    
    struct node {
    	int x, y;
    } info[1005];
    
    int cnt[1005];
    
    double getdist(int i, int j) {
    	double rx = info[i].x - info[j].x;
    	double ry = info[i].y - info[j].y;
    	double ret = rx * rx + ry * ry;
    	return ret;
    }
    
    int main() {
    	//freopen("in.txt","r",stdin);
    	int T,n;
    	cin >> T;
    	while (T--) {
    		scanf("%d", &n);
    		for (int i = 1; i <= n; i++)
    			scanf("%d%d", &info[i].x, &info[i].y);
    		double cmp = 1e15;
    		for (int i = 2; i <= n; i++) {
    			cmp = min(cmp, getdist(1, i));
    		}
    		bool flag=1;
    		memset(cnt,0,sizeof cnt);
    		for(int i=1;i<=n;i++){
    			for(int j=1;j<=n;j++){
    				if(i==j) continue;
    				if(dcmp(getdist(i,j)-cmp)==0) cnt[i]++;
    				if(dcmp(getdist(i,j)-cmp)<0){
    					flag=0;
    					break;
    				}
    			}
    		}
    		for(int i=1;i<=n;i++)
    			if(cnt[i]!=2){
    				flag=0;
    				break;
    			}
    		puts(flag?"YES":"NO");
    	}
    	return 0;
    }
    

    H - Partial Tree

    2n-2个度分配给n个点。
    原本是一个二维消费的背包。
    有一个特殊的条件就是每个点至少一个度,那么可以直接先把这些度分配给n个点。
    然后就是n-2个度任意分配的背包问题,把得到的价值修改成a[i+1]-a[1]就行了。

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    
    int f[10005];
    int dp[4400],res;
    
    int main() {
    	//freopen("in.txt","r",stdin);
    	int T,n;
    	cin >> T;
    	while (T--) {
    		scanf("%d",&n);
    		for(int i=1;i<n;i++)
    			scanf("%d",&f[i]);
    		res = (ll)f[1]*n;
    		//cout<<res<<endl;
    		for(int i=2;i<n;i++)
    			f[i]-=f[1];
    		for(int i=0;i<n;i++)
    			dp[i]=-INT_MAX;
    		dp[0]=0;
    		for(int i=1;i<n-1;i++)
    			for(int j=i;j<=n-2;j++){
    				dp[j]=max(dp[j],dp[j-i]+f[i+1]);
    			}
    		// for(int i=1;i<=n-2;i++)
    		// 	printf("%d ",dp[i]);
    		// puts("");
    		cout<<dp[n-2]+res<<endl;
    	}
    	return 0;
    }
    

    J - Chip Factory

    居然可以暴力过。

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    
    template<typename T> inline void read(T &x) {
    	x = 0; T f = 1; char ch; do {ch = getchar(); if (ch == '-')f = -1;} while (ch < '0' || ch > '9'); do x = x * 10 + ch - '0', ch = getchar(); while (ch <= '9' && ch >= '0'); x *= f;
    }
    
    template<typename A, typename B> inline void read(A&x, B&y) {read(x); read(y);}
    template<typename A, typename B, typename C> inline void read(A&x, B&y, C&z) {read(x); read(y); read(z);}
    template<typename A, typename B, typename C, typename D> inline void read(A&x, B&y, C&z, D&w) {read(x); read(y); read(z); read(w);}
    
    int a[1005];
    
    int main() {
    	//freopen("in.txt","r",stdin);
    	int T, n;
    	read(T);
    	while (T--) {
    		read(n);
    		for (int i = 1; i <= n; i++)
    			read(a[i]);
    		int Mx = 0;
    		for (int i = 1; i < n; i++)
    			for (int j = i + 1; j < n; j++)
    				for (int k = j + 1; k <= n; k++) {
    					Mx = max(Mx, (a[i] + a[j])^a[k]);
    					Mx = max(Mx, (a[i] + a[k])^a[j]);
    					Mx = max(Mx, (a[k] + a[j])^a[i]);
    				}
    		printf("%d
    ",Mx);
    	}
    	return 0;
    }
    

    然后$O(n^2 log n)$,枚举$S_i$,$S_j$从字典树删除,贪心查询$S_k$。

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn = 10000+5;
    typedef long long ll;
    ll bin[35];
    int n,m;
    ll a[maxn],x;
    
    template<typename T> inline void read(T &x){
    x=0;T f=1;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do x=x*10+ch-'0',ch=getchar();while(ch<='9'&&ch>='0');x*=f;
    }
    template<typename A,typename B> inline void read(A&x,B&y){read(x);read(y);}
    template<typename A,typename B,typename C> inline void read(A&x,B&y,C&z){read(x);read(y);read(z);}
    template<typename A,typename B,typename C,typename D> inline void read(A&x,B&y,C&z,D&w){read(x);read(y);read(z);read(w);}
    
    struct trie{
        int cnt;
        int ch[maxn*35][2];
        ll val[maxn*35];
        int ts[maxn*35];
        inline void init(){
            cnt=1;
            memset(ch[0],0,sizeof ch[0]);
            ts[0]=0;
            //memset(ts,0,sizeof ts);
        }
        inline void insert(ll a){
            int u=0;
            for(int i=32;i>=0;i--){
                ll t=a&bin[i];t>>=i;
                if(!ch[u][t]){
                    memset(ch[cnt],0,sizeof ch[cnt]);
                    val[cnt]=0;
                    ts[cnt]=0;
                    ch[u][t]=cnt++;
                }
                u=ch[u][t];
                ts[u]++;
            }
            val[u]=a;
        }
        inline void del(ll a){
            int u=0;
            for(int i=32;i>=0;i--){
                ll t=a&bin[i];t>>=i;
                u=ch[u][t];
                ts[u]--;
            }
        }
        inline ll query(ll a){
            int u=0;
            for(int i=32;i>=0;i--){
                ll t=a&bin[i];t>>=i;
                if(ch[u][t^1]&&ts[ch[u][t^1]]) u=ch[u][t^1];
                else u=ch[u][t];
            }
            return val[u]^a;
        }
    }Trie;
    
    int main(){
        //freopen("in.txt","r",stdin);
        bin[0]=1;for(ll i=1;i<=35;i++) bin[i]=bin[i-1]*2ll;
        int T,cas=1;
        for(cin>>T,cas=1;cas<=T;cas++){
            scanf("%d",&n);
            Trie.init();
            for(int i=1;i<=n;i++){
                read(a[i]);
                Trie.insert(a[i]);
            }
            ll mx=0;
            for(int i=1;i<=n;i++)
                for(int j=i+1;j<=n;j++){
                    Trie.del(a[i]);Trie.del(a[j]);
                    mx=max(mx,Trie.query(a[i]+a[j]));
                    Trie.insert(a[i]);Trie.insert(a[j]);
                }
            printf("%lld
    ",mx);
        }
        return 0;
    }
    

    L - House Building

    #include <bits/stdc++.h>
    #define rep(i,x,y) for(int i=x;i<=y;i++)
    #define per(i,x,y) for(int i=x;i>=y;i--)
    #define debug(a) cerr<<#a<<"=="<<a<<endl
    #define iout(x) printf("%d
    ",x)
    #define lout(x) printf("%lld
    ",x)
    #define iin(x) scanf("%d",&x)
    #define lin(x) scanf("%lld",&x)
    #define pb push_back
    #define mp make_pair
    #define all(x) (x).begin(),(x).end()
    #define fi first
    #define se second
    #define SZ(x) ((int)(x).size())
    using namespace std;
    typedef vector<int> VI;
    typedef long long ll;
    typedef pair<int, int> PII;
    const int mod=1e9+7;
    template<typename T> inline void read (T &x) {
        x = 0; T f = 1;
        char ch;
        do {
            ch = getchar(); if (ch == '-') f = -1;
        } while (ch < '0' || ch > '9');
        do x = x * 10 + ch - '0', ch = getchar();
        while (ch <= '9' && ch >= '0'); x *= f;
    }
    
    template<typename A, typename B> inline void read (A &x, B &y) {read (x);read (y);}
    template<typename A, typename B, typename C> inline void read (A &x, B &y, C &z) {read (x);read (y);read (z);}
    template<typename A, typename B, typename C, typename D> inline void read (A &x, B &y, C &z, D &w) {read (x);read (y);read (z);read (w);}
    template<typename A,typename B> inline A fexp(A x,B p){A ans=1;for(;p;p>>=1,x=1LL*x*x%mod)if(p&1)ans=1LL*ans*x%mod;return ans;}
    template<typename A,typename B> inline A fexp(A x,B p,A mo){A ans=1;for(;p;p>>=1,x=1LL*x*x%mo)if(p&1)ans=1LL*ans*x%mo;return ans;}
    //head
    int t;
    int a[100][100];
    int n,m;
    int main() {
    	//freopen("in.txt","r",stdin);
    	read(t);
    
    	while(t--) {
    		memset(a,0,sizeof(a));
    		scanf("%d%d",&n,&m);
    		for(int i=1;i<=n;i++) {
    
    			for(int j=1;j<=m;j++) {
    				scanf("%d",&a[i][j]);
    			}
    		}
    		int ans=0;
    		rep(i,1,n) {
    			rep(j,1,m) {
    				if(a[i][j]!=0) ans++;
    				if(a[i][j]>a[i-1][j]) ans+=a[i][j]-a[i-1][j];
    				if(a[i][j]>a[i+1][j]) ans+=a[i][j]-a[i+1][j];
    				if(a[i][j]>a[i][j-1]) ans+=a[i][j]-a[i][j-1];
    				if(a[i][j]>a[i][j+1]) ans+=a[i][j]-a[i][j+1];
    			}
    		}
    		printf("%d
    ",ans);
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    Python 学习笔记 11.模块(Module)
    Python 学习笔记 8.引用(Reference)
    Python 学习笔记 9.函数(Function)
    Python 学习笔记 6.List和Tuple
    Python 学习笔记 4.if 表达式
    Python 学习笔记 2.自省
    Python 学习笔记 3.简单类型
    Python 学习笔记 7.Dictionary
    Python 学习笔记 5.对象驻留
    Python 学习笔记 10.类(Class)
  • 原文地址:https://www.cnblogs.com/foreignbill/p/7875735.html
Copyright © 2011-2022 走看看