我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1.一个元素相邻的元素包括它本身,及他上下左右的4个元素(如果存在)。
给定矩阵的行数和列数,请计算并输出一个和谐的矩阵。注意:所有元素为0的矩阵是不允许的。
输入一行,包含两个空格分隔的整数m和n,分别表示矩阵的行数和列数。
输出包含m行,每行n个空格分隔整数(0或1),为所求矩阵。测试数据保证有解。
4 4
0 1 0 0
1 1 1 0
0 0 0 1
1 1 0 1
Solution
这道题有两种做法,一种是高斯消元解异或方程组,一种是优美的搜索,网上基本上所有的做法都是解异或方程组,我就讲一下如何用优美的搜索来做。
可以发现我们只要枚举出第一行的状态就可以计算出剩下的每一行,但是这样做只能拿到60分,因为最坏情况的复杂度是o(2^40)次方的。
我们发现这个矩阵有一种神奇的对称性,因为我们只需要枚举第一行的一半,另一半用前一半翻折过去就可以了。但是这样还是不行,只能拿到85分左右,因为如果我们o(nm)的判断答案可行性是很劣的,所以我们用类似状压的方法,f[i]是一个二进制状态,那么f[i+1]就等于f[i]^(f[i]<<1)^(f[i]>>1)^(f[i-2])
这样子就可以通过本题了。
(吐槽:一个变量名打错,调了一个多小时)
Alice和Bob居住在一个由N座岛屿组成的国家,岛屿被编号为0到N-1。某些岛屿之间有桥相连,桥上的道路是双向的,但一次只能供一人通行。其中一些桥由于年久失修成为危桥,最多只能通行两次。
Alice希望在岛屿a1和a2之间往返an次(从a1到a2再从a2到a1算一次往返)。同时,Bob希望在岛屿b1和b2之间往返bn次。这个过程中,所有危桥最多通行两次,其余的桥可以无限次通行。请问Alice和Bob能完成他们的愿望吗?
本题有多组测试数据。
每组数据第一行包含7个空格隔开的整数,分别为N、a1、a2、an、b1、b2、bn。
接下来是一个N行N列的对称矩阵,由大写字母组成。矩阵的i行j列描述编号i-1和j-1的岛屿间的连接情况,若为“O”则表示有危桥相连;为“N”表示有普通的桥相连;为“X”表示没有桥相连。
对于每组测试数据输出一行,如果他们都能完成愿望输出“Yes”,否则输出“No”。
4 0 1 1 2 3 1
XOXX
OXOX
XOXO
XXOX
4 0 2 1 1 3 2
XNXO
NXOX
XOXO
OXOX
Yes
No
4<=N<=50
0<=a1,a2,b1,b2<=N-1
1<=an,bn<=50
这一题是一道网络流。
首先建立超级源和超级汇,然后s向a1,a2连一条边权为an,bn的边,a2,b2向t连一条边权为an,bn的边,再去跑一遍最大流,再判断maxflow是否大于等于(an+bn)
但是这样显然是有问题的,会有从a1到b2,a2到b1的情况出现,因此我们再交换b1,b2,跑一遍最大流就可以了。
几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户。最常见的通配符有两个,一个是星号(”“’),可以匹配0个及以上的任意字符:另一个是问号(”?“),可以匹配恰好一个任意字符。现在需要你编写一个程序,对于给定的文件名列表和一个包含通配符的字符串,判断哪些文件可以被匹配。
第一行是一个由小写字母和上述通配符组成的字符串。第二行包含一个整数n,表示文件个数。接下来n行,每行为一个仅包含小写字母字符串,表示文件名列表。
输出n行,每行为”YES“或”NO“,表示对应文件能否被通配符匹配。
*abc?e**e
3 abcee
ppabcqexe
abcdefgee
NO
YES
YES
这一题是一道神奇的dp题。
我们定义f[i][j]表示使用到第i个通配符匹配到读入字符串的第j位,预处理一个p数组,p[t]表示第t个通配符出现的位置。
一个通配符可以把字符串分隔开,只需要确保中间的位置是相同的就可以了,这可以用hash来判断。dp方程写在代码里了,就不在赘述。
#include
#include
#include
#define ll long long
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
int n,i,j,a[50];
int m;
ll f[50],q[50];
bool fl;
inline int check(){
int x=1;
int i,j,t;
fo(i,x+1,n+1) {
f[i]=(f[i-1]>>1)^(f[i-2])^(f[i-1]<<1)^f[i-1];
if (f[i]>((ll)(q[m]-1))) f[i]-=(q[m]);
}
if (f[n+1]==0) return 1;
return 0;
}
void fill(int x){
int i;
if (fl) return;
if (x==(m/2+1+(m)%2)){
fd(i,m,x) a[i]=a[m-i+1];
f[1]=0;
fo(i,1,m) if (a[i]==1) f[1]+=(q[i-1]);
if (!check()) return;
else {
fl=true;
return;
}
}
a[x]=1;
fill(x+1);
//if (fl) return;
a[x]=0;
fill(x+1);
// if (fl) return;
}
int main(){
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
q[0]=1;
fo(i,1,45) q[i]=q[i-1]*2;
fill(1);
fo(i,1,n) {
fo(j,1,m)
if (f[i]&(q[j-1])) printf("1 "); else printf("0 ");
printf("\n");}
}
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int inf=10000007;
const int maxn=200050;
int n,i,j,a1,a2,an,b1,b2,bn,fl,tot,s,t;
int d[300],q[300],next[maxn],b[maxn],head[maxn],c[maxn],cur[maxn];
char a[100][100];
void plus(int x,int y,int z){next[++tot]=head[x];head[x]=tot;b[tot]=y;c[tot]=z;}
void add(int x,int y,int z){plus(x,y,z); plus(y,x,0);}
int bfs(){
int x,l,r,i;
l=0,r=1; q[r]=s;
memset(d,0,sizeof(d));
d[s]=1;
while (lx=q[++l];
for(i=head[x];i!=-1;i=next[i]){
if (d[b[i]]==0&&c[i]!=0) {
d[b[i]]=d[x]+1;
q[++r]=b[i];
}
}
}
return d[t];
}
int dfs(int x,int f){
int i;
if (x==t) return f;
for (int &i=cur[x];i!=-1;i=next[i]){
if (d[b[i]]==d[x]+1&&c[i]!=0) {
int di=dfs(b[i],min(c[i],f));
if (di>0) {
c[i]-=di;
c[i^1]+=di;
return di;
}
}
}
return 0;
}
void dinic(){
int i,j,ans;
tot=-1; s=0,t=n+1;
memset(head,-1,sizeof(head));
memset(next,-1,sizeof(next));
memset(c,0,sizeof(c));
add(s,a1,an),add(a2,t,an);
add(s,b1,bn),add(b2,t,bn);
fo(i,1,n)
fo(j,1,n) {
if (a[i][j]=='O') add(i,j,1);
if (a[i][j]=='N') add(i,j,inf);
}
ans=0;
while (bfs()) {
fo(i,s,t) cur[i]=head[i];
while (int di=dfs(s,inf)) ans+=di;
}
if (ans>=an+bn) fl=1; else fl=-1;
}
int main(){
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
while (scanf("%d",&n)!=EOF){
scanf("%d%d%d%d%d%d",&a1,&a2,&an,&b1,&b2,&bn);
a1++,a2++,b1++,b2++;
scanf("%d\n");
fo(i,1,n) {
fo(j,1,n)
scanf("%c",&a[i][j]);
scanf("\n");
}
fl=-1;
dinic();
swap(b1,b2);
if (fl==1) dinic();
if (fl==1) printf("Yes\n"); else printf("No\n");
}
}
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
#define ull unsigned long long
#define seed 131
using namespace std;
const int maxn=100010;
int i,n,len,j,t,f[12][maxn],p[12];
ull hash[maxn][2],q[maxn];
char s[maxn],st[maxn];
void Hash(char str[],int opt)
{
int len=strlen(str+1);
for (int i=1; i<=len; i++) hash[i][opt]=hash[i-1][opt]*seed+str[i];
}
ull get(int l,int r,int rt){
if (l>r) return -1;
return hash[r][rt]-hash[l-1][rt]*q[r-l+1];
}
int main(){
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
scanf("%s",s+1);
Hash(s,0);
q[0]=1;
fo(i,1,maxn-1) q[i]=q[i-1]*seed;
len=strlen(s+1);
fo(i,1,len) if (s[i]=='?'||s[i]=='*') p[++t]=i;
len++,s[len]='?',p[++t]=len;
scanf("%d",&n);
while (n) {
n--;
scanf("%s",st+1); Hash(st,1);
memset(f,0,sizeof(f)); f[0][0]=1;
len=strlen(st+1);
st[++len]='%';
fo(i,0,t-1) {
if (s[p[i]]=='*') fo(j,1,len) if (f[i][j-1]) f[i][j]=1;
fo(j,0,len){
if (f[i][j]&&get(j+1,j+p[i+1]-p[i]-1,1)==get(p[i]+1,p[i+1]-1,0))
if (s[p[i+1]]=='?') f[i+1][j+p[i+1]-p[i]]=1;
else f[i+1][j+p[i+1]-p[i]-1]=1;
}
}
if (f[t][len]) printf("YES\n"); else printf("NO\n");
}
}
今天这场比赛的发挥还是不错的,拿到了140分,以自己目前的水平来说基本上是完全发挥出来了,现在一周只有一场比赛打,一定要珍惜这宝贵的比赛机会,同时提升codlity和改题速度,并且补全知识漏洞。
高斯消元还是非常不熟悉
实力不济,还要加油!