5305:【题目链接】:click here~~
【题意】:
题意:
给一个图,不存在重边。
任意两个人(结点)有线上或者线下的关系,但是每个人线上和线下关系的朋友必须一样多。
求有几种方案。
=====等效于对图的边黑白染色。每个点的黑色边和白色边要一样。
【思路】:
特判如果存在边的度数为奇数的,直接输出0.
只有八个人。实际上最复杂的情况是每个人的边数都是6条。那么枚举每个人,把他们的边染色。选出一半的边染成黑色。
分析最复杂的情况C(3,6)*C(3,6)*C(2,4)*C(2,4)*C(1,2)*C(1,2)
为什么后面的C边数少了呢?因为之前枚举点的时候已经处理了这些边。所以后面就不用处理了。
剪枝:如果一个点的黑色边数 > 入度的一半,结束这次搜索
代码:
/************** 5305*************** // C #ifndef _GLIBCXX_NO_ASSERT #include <cassert> #endif #include <cctype> #include <cerrno> #include <cfloat> #include <ciso646> #include <climits> #include <clocale> #include <cmath> #include <csetjmp> #include <csignal> #include <cstdarg> #include <cstddef> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> // C++ #include <algorithm> #include <bitset> #include <complex> #include <deque> #include <exception> #include <fstream> #include <functional> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <iterator> #include <limits> #include <list> #include <locale> #include <map> #include <memory> #include <new> #include <numeric> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stack> #include <stdexcept> #include <streambuf> #include <string> #include <typeinfo> #include <utility> #include <valarray> #include <vector> using namespace std; #define rep(i,j,k) for(int i=(int)j;i<(int)k;++i) #define per(i,j,k) for(int i=(int)j;i>(int)k;--i) #define lowbit(a) a&-a #define Max(a,b) a>b?a:b #define Min(a,b) a>b?b:a #define mem(a,b) memset(a,b,sizeof(a)) typedef long long LL; typedef unsigned long long LLU; typedef double db; const int N=105; const int inf=0x3f3f3f3f; char str[N]; bool vis[N]; int dir4[4][2]= {{1,0},{0,1},{-1,0},{0,-1}}; int dir8[8][2]= {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}}; int movv[5][2]= {{1,0},{0,1},{0,0},{-1,0},{0,-1}}; inline LL read() { int c=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();} return c*f; } int n,m,t,res; struct node { int a,b; } ww[N]; int sum[N];///总共的数目 int now[N]; ///当前的friend 数目 int out[N];///已经统计过的friend 数目 void dfs(int cnt) { int j; if(cnt==m){ for(j=1; j<=n; ++j) if(now[j]*2!=sum[j]) break; if(j>n) res++; } int x=ww[cnt].a; int y=ww[cnt].b; if(sum[x]-out[x]+now[x]<sum[x]/2||sum[y]+now[y]-out[y]<sum[y]/2) return; out[x]++,out[y]++; if(now[x]+1<=(sum[x]/2)&&now[y]+1<=(sum[y]/2)){ now[x]++,now[y]++; dfs(cnt+1); now[x]--,now[y]--; } dfs(cnt+1); out[x]--,out[y]--; } int main() { t=read(); while(t--) { n=read(),m=read(); mem(sum,0); mem(now,0); mem(out,0); for(int i=0; i<m; ++i){ ww[i].a=read(); ww[i].b=read(); sum[ww[i].a]++; sum[ww[i].b]++; } if(m==0){ puts("1"); continue; } int f=1; for(int i=1; i<=n; ++i) if(sum[i]%2==1){ puts("0"); f=0;; break; } if(f){ res=0; dfs(0); printf("%d\n",res); } } return 0; }
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<vector> #include<set> #include<map> #define L(x) (x<<1) #define R(x) (x<<1|1) #define MID(x,y) ((x+y)>>1) #define eps 1e-8 using namespace std; typedef __int64 LL; #define N 100 int x[N],y[N],in[N],on[N],off[N]; int n,m; int ans; bool judge() { if(m&1) return false; for(int i=1;i<=n;i++) if(in[i]&1) return false; return true; } void dfs(int pos) { if(pos==m) { ans++; return ; } int u=x[pos],v=y[pos]; if(on[u]<in[u]/2&&on[v]<in[v]/2) //这个边为online 边 { on[u]++; on[v]++; dfs(pos+1); on[u]--; on[v]--; } if(off[u]<in[u]/2&&off[v]<in[v]/2) //这个边为off边 { off[u]++; off[v]++; dfs(pos+1); off[u]--; off[v]--; } } int main() { int i,j,t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(in,0,sizeof(in)); memset(on,0,sizeof(on)); memset(off,0,sizeof(off)); for(i=0;i<m;i++) { scanf("%d%d",&x[i],&y[i]); in[x[i]]++; in[y[i]]++; } ans=0; if(!judge()) { printf("0\n"); continue; } dfs(0); printf("%d\n",ans); } return 0; }
5302:【题目链接】:click here~~
【题意】:给你一个n*m的矩形,可以分成n*m个1*1的小矩形,再给你一个坐标(x,y),表示黑格子在n*m矩形中的位置,黑格子占一个1*1的小矩形的空间,用各种矩形去填充n*m矩形,(x,y)位置不能填,且每个去填充的小矩形都有一边是靠着n*m矩形的外框,求这些填充的小矩形在最小大小情况下的面积最大的矩形面积。
【思路】:要是填充的矩形大小最小,那么靠近边框的长度一定为1,所以只要判断在矩形内部的长度大小即可,矩形面积即为在大矩形内部的长度。
代码:// C #ifndef _GLIBCXX_NO_ASSERT #include <cassert> #endif #include <cctype> #include <cerrno> #include <cfloat> #include <ciso646> #include <climits> #include <clocale> #include <cmath> #include <csetjmp> #include <csignal> #include <cstdarg> #include <cstddef> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> // C++ #include <algorithm> #include <bitset> #include <complex> #include <deque> #include <exception> #include <fstream> #include <functional> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <iterator> #include <limits> #include <list> #include <locale> #include <map> #include <memory> #include <new> #include <numeric> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stack> #include <stdexcept> #include <streambuf> #include <string> #include <typeinfo> #include <utility> #include <valarray> #include <vector> using namespace std; #define rep(i,j,k) for(int i=(int)j;i<(int)k;++i) #define per(i,j,k) for(int i=(int)j;i>(int)k;--i) #define lowbit(a) a&-a #define Max(a,b) a>b?a:b #define Min(a,b) a>b?b:a #define mem(a,b) memset(a,b,sizeof(a)) typedef long long LL; typedef unsigned long long LLU; typedef double db; const int N=1e6+10; const int inf=0x3f3f3f3f; char str[N]; bool vis[N]; int dir4[4][2]= {{1,0},{0,1},{-1,0},{0,-1}}; int dir8[8][2]= {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}}; int movv[5][2]= {{1,0},{0,1},{0,0},{-1,0},{0,-1}}; inline LL read() { int c=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { c=c*10+ch-'0'; ch=getchar(); } return c*f; } char mon1[N],mon2[N]; int row,line,x,t,y,res; int main() { while(~scanf("%d%d%d%d",&row,&line,&x,&y)){ if(row>line){ swap(row,line); swap(x,y); } x=min(x,row-x+1); y=min(y,line-y+1); if(row==line&&(row%2==1)&&(x==y)&&x==((row+1)/2)){ cout<<row/2<<endl; continue; } res=(row+1)/2; res=max(res,min(y,row-x)); cout<<res<<endl; } return 0; }