C - Path Graph?
样例
题意:就是看给的点和边能不能形成一条路径(就一条线,没有多余的东西)
思路一:这个题我觉得就是一个大模拟,题意就表明了就是所有点连成一条线,就照着这个思路模拟出来就行,从起点出发向后走看看能不能到达终点即可(这个模拟的实质也是bfs)
前提条件:正好有(n−1)条边每个顶点的度数必须最多2,图形已连接。
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
vector<vector<int> >g(n);
for(int i=0;i<m;i++){
int u,v;
cin>>u>>v;
u-=1,v-=1;
g[u].push_back(v);
g[v].push_back(u);
}
if(m!=n-1){
cout<<"No"<<endl;
return 0;
}
for(int i=0;i<n;i++){
if(g[i].size()>2){
cout<<"No"<<endl;
return 0;
}
}
vector<bool> reach(n);
queue<int> q;
reach[0]=true; //起点从1即0开始
q.push(0);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<g[u].size();i++){
if(!reach[g[u][i]]){
reach[g[u][i]]=true;
q.push(g[u][i]);
}
}
}
for(int i=0;i<n;i++){
if(!reach[i]){
cout<<"No"<<endl;
return 0;
}
}
cout<<"Yes"<<endl;
return 0;
}
思路二:并查集(板题)
#include <bits/stdc++.h>
using namespace std;
int v[200000+5];
int find(int x){
if(v[x]==x)
return x;
v[x]=find(v[x]);
return v[x];
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) v[i]=i;
for(int i=0;i<m;i++){
int u,t;
cin>>u>>t;
int t1=find(max(u,t)),t2=find(min(u,t));
v[t1]=v[t2];
}
if (m!=n-1){
cout<<"No";
return 0;
}
for(int i=1;i<=n;i++){
v[i]=find(i);
}
int flag=1;
for(int i=1;i<=n;i++){
if(i!=1 && v[i]!=v[1]){
flag=0;
break;
}
}
if(flag) cout<<"Yes";
else cout<<"No";
}
D - Match or Not
题意:给了两个字符串,第二个字符串比第一个字符串少一个字符,第一个字符串从第一个位置到最后依次删去每个位置上的字符使其与第二个字符长度一致,看看第一个字符串的每个子字符串是否与第二个字符串相同,其中两个字符串的‘?’可以任意修改为其他的字符。
思路:就是前后找相同的长度位置,每次检索一个点检查该位置前后是否能与第二个字符串相同。
代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s,t;
cin>>s>>t;
vector<int> pre(s.size()+1,false),suf(s.size()+1,false); //前后相同的长度
pre[0]=true,suf[0]=true;
for(int i=0;i<t.size();i++){
if(s[i]==t[i] || s[i]=='?' || t[i]=='?') pre[i+1]=true;
else break;
}
reverse(s.begin(),s.end());
reverse(t.begin(),t.end());
for(int i=0;i<t.size();i++){
if(s[i]==t[i] || s[i]=='?' || t[i]=='?') suf[i+1]=true;
else break;
}
for(int i=0;i<=t.size();i++){
if(pre[i] && suf[t.size()-i]) cout<<"Yes\n";
else cout<<"No\n";
}
}
E - Karuta
题意:给了一个字符串数组,求每个字符串与其他字符串的最大前缀长度
思路:字典树板子题
代码:
#include <bits/stdc++.h>
using namespace std;
const int N=5e5+5;
int son[N][26],cnt[N],idx;
char str[N];
string s[N];
void insert(const char *str,int v){
int p=0;
for(int i=0;str[i]!='\0';i++){
cnt[p]+=v;
int u=str[i]-'a';
if(!son[p][u]) son[p][u]= ++idx;
p=son[p][u];
}
cnt[p]+=v;
}
int query(const char *str){
int p=0,ans=0;
for(int i=0;str[i]!='\0';i++){
int u=str[i]-'a';
if(!son[p][u]) return ans;
p=son[p][u];
if(cnt[p]==0) return ans;
++ans;
}
return ans;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>s[i];
insert(s[i].c_str(),1);
}
for(int i=1;i<=n;i++){
insert(s[i].c_str(),-1);
cout<<query(s[i].c_str())<<endl;
insert(s[i].c_str(),1);
}
}