思路:感觉还是题目描述有点问题。
错误思路:题意没有读清,一直以为S串去替换T串,如测试数据(ababcb替换后xyxyxy,与xyx进行匹配,大眼一看不错结果就是三个,然后突然想到最长公共子序列的出现次数,我擦,敲出代码发现就是结果不对,尴尬,什么原因,找了半天没有发现错误何在,最后发现xyxyxy去匹配xyx不是3是4,(xyxyxy)(xyxyxy)(xyxyxy)(xyxyxy))。噢噢,一下回到解放前。那估计就是题目理解错误了。
最长公共子序列及个数:求最长是一个很简单的dp,但是求最长的个数,以前没有接触过,若a[i]!=b[j]的时候,判一下f[i][j]和f[i-1][j],f[i][j-1]分别相不相等,如果相等就加上对应的方案数,再判和f[i-1][j-1]是否相等,相等就再减去[i-1][j-1]的方案数;a[i]==b[j]的时候,用[i-1][j-1]的方案数,然后如果f[i-1][j]或者[i][j-1]和f[i][j]相等的话,也加上对应的方案数。(注意必要时,可以使用滚动数组进行转态压缩)
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#define mod 100000000
using namespace std;
string a,b;
int f[5005][5005],g[5005][5005];
int main(){
cin>>a>>b;
int l1=a.length()-1,l2=b.length()-1;
a=' '+a,b=' '+b;
for(int i=0;i<=l1;i++)g[i][0]=1;
for(int i=0;i<=l2;i++)g[0][i]=1;
for(int i=1;i<=l1;i++)
for(int j=1;j<=l2;j++)
{
if(a[i]==b[j])
{
f[i][j]=f[i-1][j-1]+1;
g[i][j]=g[i-1][j-1];
if(f[i][j]==f[i][j-1])g[i][j]=(g[i][j]+g[i][j-1])%mod;
if(f[i][j]==f[i-1][j])g[i][j]=(g[i][j]+g[i-1][j])%mod;
}
else
{
f[i][j]=max(f[i-1][j],f[i][j-1]);
if(f[i][j]==f[i-1][j])g[i][j]=(g[i][j]+g[i-1][j])%mod;
if(f[i][j]==f[i][j-1])g[i][j]=(g[i][j]+g[i][j-1])%mod;
if(f[i][j]==f[i-1][j-1])g[i][j]-=g[i-1][j-1],g[i][j]=(g[i][j]+mod)%mod;
}
}
cout<<f[l1][l2]<<endl<<g[l1][l2]%mod;
return 0;
}
正确:看了一下讨论区,看不懂哎,运行了一下代码,搞得我想吐血。什么情况,对应S和T串都需要编码,然后还是连续子串,编码竟然是这样编码的XYX==010,ababcb不能直接编码,只能截取3个一段落,aba、bab、abc、bcb,编码分别是010、010、012、010,看出什么了吗?竟然是按照子串的下标进行编码,如aba,第二个a在下标0的时候出现过了。好吧,已哭晕在厕所(貌似这个还不是100%通过,超时)
#直接上讨论群区的代码了
def get(d,key,value):
if(key not in d):
d[key] = value
return d[key]
def solve(S, T):
Tflag = []
tempdict = dict()
for i in range(len(T)):
Tflag.append(get(tempdict,T[i],i))
#得到对应索引列表
#print(Tflag)
count = 0
for i in range(0,len(S)-len(T)+1):
string = S[i:i+len(T)]
tempdict = dict()
Sflag = []
for j in range(len(string)):
Sflag.append(get(tempdict,string[j],j))
#print(Sflag)
if Tflag == Sflag:
count += 1
return count
print(solve("ababcb","xyx"))
思路:一笔画问题,只要整个图互联互通即可,还不对,还不用使用欧拉回路判定(每个边只能访问一次)。感觉只要是一个连通图即可,bfs+邻接矩阵判定即可。看了一下测试数据,同一集合不能相连接,不同集合必须要直接相连接。又凉凉了。
看了一下讨论区,感慨一下,数学真强大,把与顶点A不相连接的顶点和与顶点A相连接的顶点找出来;与顶点A不相连接的顶点一定在同一集合,相连的一定不能在同一集合;注意题目要求,那么只需要两次for循环遍历即可,与A不相连接的顶点(同一集合)必须和A相连接的顶点都相连接(不同集合),这样才符合题意。
package com;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class hqh1 {
public static class Node{
public int value;
public ArrayList<Node> nexts;
public boolean pass;
public Node(int value){
this.value = value;
nexts = new ArrayList<>();
pass = false;
}
}
public static void process(Scanner in){
int n = in.nextInt();
int m = in.nextInt();
HashMap<Integer, Node> map = new HashMap<>();
for(int i = 0; i < n; i++){
map.put(i+1, new Node(i+1)); //建立索引,n个下标对应顶点
}
for(int i = 0; i < m; i++){
int f = in.nextInt();
int s = in.nextInt();
Node nf = map.get(f); //根据下标,获取顶点
Node ns = map.get(s);
nf.nexts.add(ns); //对应顶点,添加相连接的顶点
ns.nexts.add(nf);
}
Node n1 = map.get(1); //取出顶点1
map.remove(1);
List<Node> xl = n1.nexts; //与顶点1相关的顶点
List<Node> nxl = new ArrayList<>();
for (Map.Entry<Integer, Node> entry : map.entrySet()) {
if(!xl.contains(entry.getValue())){ //与顶点1无关的顶点
nxl.add(entry.getValue());
}
}
//判断,按照要求,与顶点1无关的顶点一定在同一集和,并且与其它顶点都相连
boolean pan = false;
for(Node node : nxl){ //无关顶点
for(Node node1: xl){ //有关顶点
if(!node.nexts.contains(node1)){
pan = true;
break;
}
}
}
if(pan){
System.out.println("No");
}else{
System.out.println("Yes");
}
}
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
for(int i = 0; i < n; i++){
process(in);
}
}
}
#include<stdio.h>
#include <algorithm>
#include<vector>
#include<iostream>
using namespace std;
int main(){
int T,n,m,x,y;
scanf("%d",&T);
while(T--){
vector<vector<int> >List(1005);
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d",&x,&y);
List[x].push_back(y);
List[y].push_back(x);
}
//与顶点1相连的顶点
vector<int> yes=List[1];
vector<int> no;
//找与与顶点1不相连的顶点
for(int i=2;i<=n;i++){
if(find(yes.begin(),yes.end(),i)==yes.end()){ //没找到
no.push_back(i);
}
}
//判断
int flag=0;
for(int i=0;i<no.size();i++){ //顶点no[i]
for(int j=0;j<yes.size();j++){ //顶点yes[j]
//判断顶点no[i]是否连接顶点yes[j]
if(find(List[no[i]].begin(),List[no[i]].end(),yes[j])==List[no[i]].end()){ //没找到
flag=1;
break;
}
}
if(flag==1) break;
}
printf("%s\n",flag?"No":"Yes");
}
}
/*
2
5 7
1 3 1 5 2 3 2 5 3 4 4 5 3 5
4 3
1 2 2 3 3 4
*/