比较菜啊本人,只写出来了1~2题,但是后来订正完了的精神也是值得鼓励的~
不多说,总结一下吧
T1.根据题意进行模拟,每个奇数行用'#'涂满,然后判断是否是4的倍数涂旁边的'#'答案就可以出来了~
#include<bits/stdc++.h>
using namespace std;
int n,m;
int b[1000][1000];
int main()
{
cin>>n>>m;
int x=0,y=0;
int sx=0,sy=1;
int judge=0;
for(int i=1;i<=n;i+=2)
for(int j=1;j<=m;j++)
b[i][j]=1;
for(int i=2;i<=n;i+=2){
if(i%4==2) b[i][m]=1;
else b[i][1]=1;}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
cout<<((b[i][j]==1)?'#':'.');
cout<<"\n";}
return 0;
}
T2.一遍dfs或者bfs判断这个点是否有没有走过,我们记录他的父节点,然后就可以出来了。
优化,一个字母出现的次数>=4才搜索
#include<bits/stdc++.h>
using namespace std;
int n,m;
int b[100][100];
int book[100][100];
int du[300],vis[200];
int temp[4][2]={{1,0},{-1,0},{0,-1},{0,1}};
int ok=0;
void dfs(int x,int y,int fx,int fy,int color)
{
if(ok) return ;
for(int k=0;k<4;k++)
{
int u=x+temp[k][0];
int v=y+temp[k][1];
if(u<=0||v<=0||u>n||v>m||(u==fx&&v==fy)) continue;
if(b[u][v]==color)
{
if(book[u][v]==color) {ok=1;return ;}
book[u][v]=color;
dfs(u,v,x,y,color);
}
}
}
int main()
{
cin>>n>>m;
char c;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
c=getchar();
while(c=='\n'||c=='\r')
c=getchar();
b[i][j]=c;
du[c]++;
}
for(int k=0;k<=200;k++)
if(du[k]>=4)
{
ok=0;
memset(book,0,sizeof(book));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(b[i][j]==k&&book[i][j]==0)
{
book[i][j]=k;
dfs(i,j,-1,-1,k);
if(ok) {cout<<"Yes\n";return 0;}
}
}
cout<<"No\n";
return 0;
}
T3.拓扑排序,因为前面的字母的都比后面的要大,于是就可以想到topusort,给每一个节点连一条有向边,然后计算入度就可以了。
注意:abc ab这样的字母要进行特判,因为这种情况是不存在的。
这题打到一半,快出结果了,没时间上交了。虽然思路也是yy来的(逃)
#include<bits/stdc++.h>
using namespace std;
int n;
char s[200],pre[200];
int in[200];
int ans[200];
vector<int> G[123];
int flag=0;
int topusort()
{
queue<int> q;
for(int i=0;i<26;i++)
if(!in[i]) q.push(i);
int top=0;
while(!q.empty())
{
int x=q.front();q.pop();
ans[++top]=x;
for(int i=0;i<G[x].size();i++)
{
int m=G[x][i];
if(in[m]==1) q.push(m);
if(in[m]) in[m]--;
}
}
if(top!=26||flag)
cout<<"Impossible\n";
else
{
for(int i=1;i<=top;i++)
cout<<char(ans[i]+'a');
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>s;
int ok=0;
for(int j=0;j<min(strlen(s),strlen(pre));j++)
{
if(s[j]!=pre[j])
{
G[pre[j]-'a'].push_back(s[j]-'a');
in[s[j]-'a']++;
ok=1;
break;
}
}
if(!ok&&strlen(pre)>strlen(s))
{flag=1;break;}
strcpy(pre,s);
}
topusort();
/*for(int i=0;i<122;i++)
if(G[i].size())
cout<<G[i][0]<<endl;*/
return 0;
}
T4.exgcd,当ax+by=1有解得情况是,x,y互质,于是就可以转换成一个背包问题,具体看代码批注。
//找出为1的最大公约数,把他看成背包问题,看每个数对因子的贡献
//每个数都有选或者不选,
#include<bits/stdc++.h>
using namespace std;
int n;
int l[300000],c[300000];
map<int,int> dp;
int gcd(int a,int b)//gcd(a,b)=gcd(b,a);
{
return b==0?a:gcd(b,a%b);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>l[i];
for(int i=1;i<=n;i++)
cin>>c[i];
dp.clear();
dp[0]=0;//map初始化为0
map<int,int> ::iterator it;//为std::pair的类型dp[a]=b,first=a,second=b;
for(int i=1;i<=n;i++)
{
for(it=dp.begin();it!=dp.end();it++)//左闭右开stl
{
int t=it->first;
int tt=gcd(l[i],t);
if(dp.count(tt))//返回该元素出现的个数
dp[tt]=min(dp[tt],it->second+c[i]);
else dp[tt]=it->second+c[i];
}
}
if(!dp.count(1)) cout<<"-1\n";
else cout<<dp[1]<<endl;
return 0;
}
T5.网络流问题。(前排的大神用二分图匹配做出来了,待会儿听听讲解吧orz~)我的想法也是参考网上的大神的
首先我们可以知道相邻两个是素数的话一定是异奇偶,因为素数为2的情况已经被排除。于是我们就可以建立一个虚拟巨大节点,以及虚拟巨大汇点,然后建立一条从源点到偶数节点容量为2的边,因为一个数旁边有两个奇数,同理再建立奇数节点到汇点容量为2的边。我们再分别枚举所有的节点,找出和为素数的节点,并连上一条为1的边,然后跑一边最大流(我不会写最大流,于是就拷贝了之前写的,发现竟然有错误恼)。
如果流==n那就存在,一遍dfs跑出满容量的边,然后输出就可以了。
#include<bits/stdc++.h>
#define maxn 2140000
using namespace std;
struct{int to,next,w;}e[maxn];
int head[maxn],ly[maxn],lx[maxn],a[maxn],prime[maxn],cur[maxn],gap[maxn],h[maxn],vis[maxn];
vector<int> mp[12004];
int cnt=0,n,ss,tt;
void add(int u,int v,int w){
e[cnt].to=v;e[cnt].w=w;e[cnt].next=head[u];head[u]=cnt++;
}
void init()
{
prime[1]=1;
for(int i=2;i<=sqrt(165540);i++)
if(!prime[i])
for(int j=i*i;j<=165540;j+=i)
prime[j]=1;
}
void get()
{
ss=n+1;tt=ss+1;
int cntx=0,cnty=0;
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++)
{
if(a[i]%2==0)
{
add(ss,i,2);add(i,ss,0);
lx[cntx++]=i;
}
else
{
add(i,tt,2);add(tt,i,0);
ly[cnty++]=i;
}
}
for(int i=0;i<cntx;i++)
for(int j=0;j<cnty;j++)
if(prime[a[lx[i]]+a[ly[j]]]==0)
add(lx[i],ly[j],1),add(ly[j],lx[i],0);
}
int isap(int x,int fr)
{
if(x==tt)
return fr;
int rest=0;
for(int i=cur[x];~i;i=e[i].next)
{
int j=e[i].to;
if(h[j]+1==h[x]&&e[i].w)
{
int f=isap(j,min(e[i].w,fr-rest));
e[i].w-=f;
e[i^1].w+=f;
rest+=f;
if(rest==fr) return fr;
if(e[i].w) cur[x]=i;
}
}
--gap[h[x]];
if(!gap[h[x]]) h[ss]=n+4;
h[x]++;gap[h[x]]++;
cur[x]=head[x];
return rest;
}
int maxflow()
{
int ans=0;
for(int i=1;i<=n+2;i++) cur[i]=head[i];
while(h[ss]<n+4)
ans+=isap(ss,1e9);
return ans;
}
int dfs(int x,int num)
{
mp[num].push_back(x);
vis[x]=1;
for(int i=head[x];~i;i=e[i].next)
{
int j=e[i].to;
if(vis[j]) continue;
if(j!=ss&&j!=tt)
if((i%2==0&&e[i].w==0)||(i%2==1&&e[i^1].w==0))
dfs(j,num);
}
}
void output(int num)
{
for(int i=1;i<=num;i++)
{
cout<<mp[i].size();
for(int j=0;j<mp[i].size();j++)
cout<<" "<<mp[i][j];
cout<<"\n";
}
}
int main()
{
init();
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
get();
int tmp=maxflow();
//cout<<tmp<<endl;
if(tmp==n)
{
int num=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) if(!vis[i]) dfs(i,++num);
cout<<num<<endl;
output(num);
}
else cout<<"Impossible\n";
return 0;
}
今天的状态还算比较不错吧,毕竟我是一只蒟蒻,up++;