您的位置:首页 > 其它

WHUST 2015 Summer Contest #11

2015-08-31 16:44 429 查看
网址: 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
--+-
+--+
-+--
--+-
*/


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: