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;
    }
    
  • 相关阅读:
    [转]关于tomcat 中的 tomcat-users.xml 配置不生效原因
    sql准确判断某个ip
    PS快捷键
    指向指针的指针
    eclipse项目中.classpath文件详解
    使用MyBatis_Generator工具jar包自动化生成Dto、Dao、Mapping 文件
    eclipse同一个工作空间下分开多个项目
    Java程序发送邮件
    Java中实现短信发送
    Java如何判断字符串中包含有全角,半角符号
  • 原文地址:https://www.cnblogs.com/foreignbill/p/7875735.html
Copyright © 2011-2022 走看看