WHUST 2015 Summer Contest #11

网址: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=89986#overview

 

自己一个人做的好醉……………………

Problem D. Dinner Problem Gym 100342D

题意: 1<=k<=n<=100 k个人在n天中做饭,没人至少做一天的饭,问一共有多少种情况。。  自己犯了2B错误,容斥公式写错了。DP理解不了,纠结了一天。。

import java.util.*;
import java.io.*;
import java.math.*;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws FileNotFoundException
	{
		// TODO Auto-generated method stub
		Scanner cin = new Scanner (new File("dinner.in"));
		PrintWriter cout = new PrintWriter(new File("dinner.out"));
		//Scanner cin = new Scanner (System.in);
		BigInteger [][] C = new BigInteger [110][110];
		
		C[0][0]=BigInteger.ONE;
		for (int i=1;i<=100;i++) 
		{
			C[i][0]=C[i][i]=BigInteger.ONE;
			for (int j=1;j<i;j++) {
				C[i][j] = BigInteger.ZERO;
				C[i][j]=C[i][j].add(C[i-1][j-1]);
				C[i][j]=C[i][j].add(C[i-1][j]);
			}
		}
		int n,k;
		while(cin.hasNext())
		{
			BigInteger ans = BigInteger.ONE;
			k = cin.nextInt();
			n = cin.nextInt();
			for (int i=1;i<=n;i++)
			{
				BigInteger tmp = new BigInteger(String.valueOf(k));
				ans = ans.multiply(tmp);
			}
			
			int cur=0;
			for (int i=1;i<=k;i++){
				BigInteger tp = C[k][i];
				for (int j=1;j<=n;j++)
				{
					BigInteger tmp = new BigInteger(String.valueOf(k-i));
					tp = tp.multiply(tmp);
				}
				if (cur==0) {
					ans=ans.subtract(tp);
				}
				else {
					ans=ans.add(tp);
				}
				//System.out.println(tp);
				//System.out.println(ans);
				cur=1-cur;
			}
			cout.println(ans);
			//System.out.println(ans);
		}
		cin.close();
		cout.close();
	}

}

  E - Minima Gym 100342E

题意:类似poj一道窗格移动的题目,裸的单调队列, 但是那个z=f(y), -2^31<=z<=2^31-1 y-z可以被2^32整除, 这个东西看得有点醉, 不理解, 后来别人说了下是自然溢出的意思…………

#include<bits/stdc++.h>
#define maxn 30000010
using namespace std;

int f[maxn];
struct node
{
    int x,y;
    node(int x, int y):x(x),y(y){}
};
deque<node> Q;

int main(void)
{
    freopen("minima.in","r",stdin);
    freopen("minima.out","w",stdout);
    int n,m,k,a,b,c;
    scanf("%d%d%d%d%d%d",&n,&m,&k,&a,&b,&c);
    for (int i=1;i<=k;i++) scanf("%d",&f[i]);
    for (int i=k+1;i<=n;i++) f[i]=a*f[i-2]+b*f[i-1]+c;
    //for (int i=1;i<=n;i++) f[i]=i;//printf("%d ",f[i]);
    for (int i=1;i<=m;i++)
    {
        while(!Q.empty()&&f[i]<=Q.back().x) Q.pop_back();
        Q.push_back(node(f[i],i));
    }
    long long ans=Q.front().x;
    //cout<<ans<<endl;
    for (int i=m+1;i<=n;i++)
    {
        while(!Q.empty()&&i-Q.front().y>=m) Q.pop_front();
        while(!Q.empty()&&(f[i]<=Q.back().x||Q.back().y-i>=m)) Q.pop_back();
        Q.push_back(node(f[i],i));
        ans+=Q.front().x;
        //cout<<Q.front().x<<" ";
    }
    cout<<ans<<endl;
}
/*
10 3 2
1 1 0
0 1
*/

J - Triatrip Gym 100342J

题意:给定一个有向无权图,问存在多少 i->j->k->i 这样的圈。。

解法:利用bitset优化, 一个很巧妙的方法存储下边和反边, 那么对于每一对(i,j) 结果就是 (f[i]&g[j]).cout(), 累加就是最后结果  

 

#include<bits/stdc++.h>
#define maxn 1510
using namespace std;

bitset<maxn> f[maxn],g[maxn];
char s[maxn][maxn];

int main(void)
{
    freopen("triatrip.in","r",stdin);
    freopen("triatrip.out","w",stdout);
    int n;
    scanf("%d",&n);
    for (int i=0;i<n;i++)
    {
        scanf("%s",s[i]);
        f[i].reset();
        g[i].reset();
    }
    for (int i=0;i<n;i++)
        for (int j=0;j<n;j++)
    {
            if (s[i][j]=='+') f[i][j]=1,g[j][i]=1;
    }

    long long ans=0;
    for (int i=0;i<n;i++)
        for (int j=0;j<n;j++)
    {
        if (f[i][j]) ans+=(f[j]&g[i]).count();
    }
    cout<<ans/3<<endl;
}
/*
4
--+-
+--+
-+--
--+-
*/

  

 

posted on 2015-08-31 16:44  wzb_hust  阅读(183)  评论(0编辑  收藏  举报

导航