转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526 by---cxlove
A:判断一下3*n与K的关系就OK了,假设所有课都是3,如果还有分,那么随意安排,如果不够,则把部分课程变为2
B:k*(n+1)|(4*n)求出最小的k就行了,gcd(n+1,n)==1很明显,就看n+1里面有几个2因子就OK了
C:可以推出答案只有3种,-1,1,2
首先处理掉-1的情况,也就是初始只有0,1,2个#的情况
然后只需要枚举#,然后进行搜索,判断是否能够走到所有的点,就OK了
否则就是2
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#include<algorithm>
#define N 210005
#define inf 100000000
#define MOD 100000007
#define LL long long
#define mem(a,b) memset(a,b,sizeof(a))
#define Key_value ch[ch[root][1]][0]
#define _match(a,b) ((a)==(b))
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
int way[4][2]={0,1,0,-1,1,0,-1,0};
char str[55][55];
int flag[55][55],n,m;
bool check(){
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(str[i][j]=='#'&&flag[i][j]==0)
return true;
return false;
}
void dfs(int x,int y){
flag[x][y]=1;
for(int i=0;i<4;i++){
int X=x+way[i][0],Y=y+way[i][1];
if(X>=0&&X<n&&Y>=0&&Y<m&&!flag[X][Y]&&str[X][Y]=='#')
dfs(X,Y);
}
}
bool slove(){
mem(flag,0);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(str[i][j]=='#'){
dfs(i,j);
return check();
}
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
int cnt=0;
for(int i=0;i<n;i++){
scanf("%s",str[i]);
for(int j=0;j<m;j++)
if(str[i][j]=='#')
cnt++;
}
if(cnt<3){printf("-1\n");continue;}
bool ans=true;
for(int i=0;i<n&&ans;i++)
for(int j=0;j<m&&ans;j++)
if(str[i][j]=='#'){
str[i][j]='.';
if(slove())
ans=false;
str[i][j]='#';
}
printf("%d\n",ans?2:1);
}
return 0;
}
D:搜索,每一步两种情况,这样的复杂度是2^30,不过可以注意到,其中有一种操作是异或,利用异或的性质,最多异或一次,两次及以上肯定不是最优的,加上这个剪枝就OK了
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#include<algorithm>
#define N 210005
#define inf 100000000
#define MOD 100000007
#define LL long long
#define mem(a,b) memset(a,b,sizeof(a))
#define Key_value ch[ch[root][1]][0]
#define _match(a,b) ((a)==(b))
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
int a[40][40],b[40],p[40],k[40];
int n,u,t;
LL ans;
void dfs(int dep,int two){
LL tmp=0;
for(int i=0;i<n;i++) tmp+=(LL)a[dep][i]*k[i];
if((u-dep)%2==0)ans=max(ans,tmp);
if(dep==u) return;
for(int i=0;i<n;i++) a[dep+1][i]=a[dep][p[i]]+t;
dfs(dep+1,0);
if(two==1) return;
for(int i=0;i<n;i++) a[dep+1][i]=(a[dep][i]^b[i]);
dfs(dep+1,1);
}
int main(){
while(scanf("%d%d%d",&n,&u,&t)!=EOF){
for(int i=0;i<n;i++)scanf("%d",&a[0][i]);
for(int i=0;i<n;i++)scanf("%d",&b[i]);
for(int i=0;i<n;i++)scanf("%d",&k[i]);
for(int i=0;i<n;i++)scanf("%d",&p[i]),p[i]--;
ans=-(1ll<<60);
dfs(0,0);
printf("%I64d\n",ans);
}
return 0;
}