2013.12.09
A:
POJ 1306
算 n!/m!/(n-m)! 1<=n,m<=100 边乘 边除即可 因为, 结果不会超过 __int64 的
B:
POJ 1742
起初一看是 多重背包 求方案数 于是按照纯 多重背包写了一下 TLE 之后可以 dp O(n*m) 可以过
code:
#include
#include
#include
#include
using namespace std;
#define INF 1000000000
int f[100005];
int sum[100005];
int v[105],c[105];
int main()
{
//freopen("in.txt","r",stdin);
int k,n,m;
while(scanf("%d%d",&n,&m),n||m)
{
for(int i = 1; i<=n; i++)
scanf("%d",&v[i]);
for(int i = 1; i<=n; i++)
scanf("%d",&c[i]);
memset(f,0,sizeof(f));
f[0] = 1;
int ans = 0;
for(int i=1; i<=n; i++)
{
memset(sum,0,sizeof(sum));
for(int j = v[i]; j<=m; j++)
{
if(!f[j] && f[j-v[i]] && sum[j-v[i]]
C:
HDU 1686
KMP 待补。。。。
D:
HDU 1213
并查集 水题
E:
HDU 3863
其实 ,是一个 很逗的 题目, 两个人游戏, 而且 两个人除了 谁先手外, 其余 的处境 一样, 而且 先手 没有任何 坏处,只有好处,于是没有什么博弈的高级内容,先手的 那个人一定赢, 于是 只有一个字符串输出而已。
F:
POJ 3660
给定拓扑关系的一部分 ,求 有多少人 的次序可以确定。 智商被压制
建图,floyd 跑一遍,则 可以分别算出, 可以打败他的人数 和 他可以打败的人数 , 如果 相加 等于n-1则 这个人的次序可以确定,反之 同理
#include
#include
#include
#include
using namespace std;
#define INF 1000000000
int n,m;
int d[110][110];
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
int x,y;
memset(d,0,sizeof(d));
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
d[x][y]=1;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int k=1;k<=n;k++)
{
if(d[j][k]) continue;
if(d[j][i] && d[i][k]) d[j][k]=1;
}
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
int tmp=0;
for(int j=1;j<=n;j++)
{
if(d[i][j]) tmp++;
if(d[j][i]) tmp++;
}
if(tmp>=n-1) ans++;
}
printf("%d\n",ans);
}
return 0;
}
G :
CodeForces 330A
纯水
n个点 , m条边不可建边, 求 建立最少的边 使得 each point to any point 都可以通过 至多两条边 到达 。
如果看到 题目的 数据范围
这说明, 肯定存在 一个点 可以到 其他任一点建边 不受限制,总边数至少为n-1.
则, 可以从这个 点出发,到其他个点建边即可。。
下面两个题目,没看题。。
I :
CodeForces 331A1
J:
SPOJ GSS1
*****************************************************************************************************************************************************************************************
**************************************************************************************************************************************************************************
//[a,b] [c,d] 区间内分别取x,y 使得 (x+y)%p==m成立 给定a,b,c,d,p,m 0<=a<=b<=10^9 c,d同. p,m同样[0,10^9].
// 求 范围内组成等式的概率是多少.
//一共组成的 元素 (b-a+1)*(d-c+1) 个 可以组成矩阵,之后把矩阵的第i行相对于上一行i-1行向右移动一下,使得每列的元素的值相等
//这就形成了一个平行四边形,从左下定点 和右上定点 做垂线,可以分割成两个三角形 和 一个平行四边形(有可能是矩形或者平行四边形)
//两个三角形的 符合条件的元素 随着列数的增加 呈等差数列,矩形则是 每行的符合条件的元素*列数.加一起。求分数即可.
#include
#include
#include
using namespace std;
#define INF 1000000005
typedef __int64 LL;
LL a,b,c,d,m,p,l,r;
LL sol(LL x,LL y,int fl)
{
if(y
y || l*p+m>y || l*p+m
=0? (l-r+1):0; LL a1; if(fl==1) a1=r*p+m-x+1; else if(fl==2) a1=y-l*p-m+1; LL n=l-r+1; return n*a1+n*(n-1)*p/2; } LL gcd(LL x,LL y) { if(y==0) return x; return gcd(y,x%y); } int main() { //freopen("in.txt","r",stdin); int t,time=0; scanf("%d",&t); while(t--) { scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&p,&m); LL tmp1,tmp2,tmp3; if(b+c
// 20000只牛,每个牛在温度区间[A.B]内产奶y,小于A 产奶x,大于B产奶z。对于所有的牛x,y,z都一样每个牛 有A[i],B[i].
//温度区间0-10^9 , 所以要考虑20000只牛 这个小数据,最多有40000个点分割温度区间,由小到大遍历每个区间即可(相对于前一个区间是
//增大还是减小),唯一注意的是 y对应的区间是[A,B],都是闭区间,注意处理[a,b] [b,c] 级边界重合的情况.
/*
ID: tyf19938
LANG: C++
TASK: milktemp
*/
#include
#include
#include
using namespace std;
#define N 20005
int n,ma,tmp,x,y,z;
struct node
{
int x,f;
}num[2*N];
bool cmp(node a,node b)
{
return a.x
=2*n) break;
ma=max(ma,tmp);
if(num[i].x==num[i+1].x) continue;
tmp+=ad; ad=0;
ma=max(ma,tmp);
}
printf("%d\n",ma);
}
return 0;
}
//给定一个有向图,一共N(N<=50) 个点,给定矩阵 代表从i到j有一条容量为d[i][j]的有向边。给一个数k,可以给任意存在的有向边添加容量
//满足 添加的总容量<=k。 求 点1为源点, 点N 为汇点,的 网络流的最大值.
//建图: 对于d[i][j]!=0的边 添加 一种边为 i->j 容量为 d[i][j] 费用为0 , 另一种 i->j 容量为INF(无穷),费用为1.
//求 source->sink的满足费用<=k的最大流.
#include
#include
#include
#include
using namespace std;
#define INF 1000000000
#define N 51
int n,k,pre[N],dis[N],inq[N],tot,hh[N],start,end;
struct node
{
int u,v,w,c,next;
}edge[6*N*N];
void init()
{
tot=0;
memset(hh,-1,sizeof(hh));
}
void add(int u,int v,int w,int c)
{
edge[tot].u=u; edge[tot].v=v;
edge[tot].w=w; edge[tot].c=c;
edge[tot].next=hh[u];
hh[u]=tot++;
}
int spfa()
{
queue
q; memset(inq,0,sizeof(inq)); memset(pre,-1,sizeof(pre)); for(int i=1;i<=n;i++) dis[i]=INF; dis[start]=0; inq[start]=1; q.push(start); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=hh[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(edge[i].w && dis[v]>dis[u]+edge[i].c) { pre[v]=i; dis[v]=dis[u]+edge[i].c; if(!inq[v]) { inq[v]=1; q.push(v); } } } inq[u]=0; } if(dis[end]==INF) return -1; return dis[end]; } int maxx() { int re=0; while(1) { int now=spfa(); if(now<0) break; int tmp=INF; for(int i=pre[end];i!=-1;i=pre[edge[i].u]) tmp=min(tmp,edge[i].w); if(k
//给定序列S,可以构成矩阵b b[i][j]=s[i]*s[j] , 给出a , 求 矩阵b中 多少个矩形块, 其和为a。
//设sum= 第i 到第j 行 和 第x 到第y列 构成的矩形块的和, 可以化简得出: sum=(s[i]+s[i+1]+..+s[j-1]+s[j])*(s[x]+s[x+1]+..+s[y-1]+s[y])
//即求 b=sum的组成个数。 O(n^2)可以枚举出s[i] 到s[j]的 可能取值.
//之后,对于输入的a, 枚举1~sqrt(a) 的 值f 是否是上面取得的值,而且a%f==0 && a/f也是上面的取值,
//注意, a==0的情况,注意使用64位。
#include
#include
#include
#include
#include
//1000行数据,每行数据范围0~10000,之后有q个(200000)询问,给定两个数a,b , 问是否同时出现在某一行中。
//如果直接开数组[1000][10000],之后对于每个询问,遍历所有的行,会TLE。
//上面数组中存储的 是0 1 矩阵, 每一列是 该数在某行中是否出现,可以把这最多1000位压缩,可以使用bitset或者用32个int拼成1000位。
//[1000][32],这样不仅 内存缩减 而且,查询时 只需要把a 和 b的 1000位(32个int) 取与,出现非零,则该数出现同时出现在某一列中。
//code 1 32个int 拼接。
#include
#include
#include
using namespace std;
#define INF 1000000000
#define N 11000
int d[N][35],n,q;
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
int tmp,s;
memset(d,0,sizeof(d));
for(int i=0;i
#include
#include
#include
using namespace std; #define INF 1000000000 int n; bitset<1003> d[10003],che; int main() { //freopen("in.txt","r",stdin); while(scanf("%d",&n)!=EOF) { int x,tmp; for(int i=1;i<=10000;i++) d[i].reset(); for(int i=1;i<=n;i++) { scanf("%d",&x); while(x--) { scanf("%d",&tmp); d[tmp].set(i); } } int q,a,b; scanf("%d",&q); while(q--) { scanf("%d%d",&a,&b); che=d[a]&d[b]; if(che.any()) printf("Yes\n"); else printf("No\n"); } } return 0; }