P8604 [蓝桥杯 2013 国 C] 危险系数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
通过这题了解了存图的基本方法:邻接表
首先用vector二维数组存图
然后就是对这张图进行一个dfs的遍历
尝试从起点到终点的所有路径
从而找到符合条件的“关键点”
#include<bits/stdc++.h>
using namespace std;//邻接表的实现
const int N=100005;int tot,ans;int cnt[N];
int n,m;int st,ed;bool vis[N];//标记数组
vector<int>G[N];//定义二维vector
void dfs(int now)
{
if(now==ed)//到达终点
{
tot++;//统计总共有几条路可达
for(int i=1;i<=n;i++)
{
if(vis[i])//此条路径下访问的所有节点
cnt[i]++;//统计该节点被访问的次数
}
return;
}
for(int i=0;i<G[now].size();i++)//遍历当前节点所有通路
{
int to=G[now][i];//下一节点
if(!vis[to])//判断是否访问过vis[to]
{
vis[to]=true;//标记已访问
dfs(to);
vis[to]=false;//取消标记
}
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
int a,b;
cin>>a>>b;
G[a].push_back(b);//在a节点上存储a的所有通路
G[b].push_back(a);
}//存图完成
cin>>st>>ed;
vis[st]=true;
dfs(st);
for(int i=1;i<=n;i++)
{
if(cnt[i]==tot)//该节点被访问次数等于可达路径总数 说明该点为关键点
{
ans++;
}
}
cout<<ans-2;//减去起点终点
}
P3916 图的遍历 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这题的思想是反向dfs
要求从起点能到达的最大节点
反着想从最大节点开始
他遍历到的节点就必然是他最大
并且只要标记过就不需要重复遍历
因为是有向图 有些点不能被遍历到
所以每个点都dfs一次
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
vector<int>G[N];
int n,m;bool bj[N];int max1[N];int zd;
void dfs(int jd)
{
if(!max1[jd])
{
max1[jd]=zd;
}
else
{
return;
}
for(int i=0;i<G[jd].size();i++)
{
int to=G[jd][i];
if(!bj[to])
{
bj[i]=true;
dfs(to);
bj[i]=false;
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
G[b].push_back(a);
}
for(int i=n;i>=1;i--)
{
zd=i;
dfs(i);
}
for(int i=1;i<=n;i++)
{
cout<<max1[i]<<' ';
}
}
P1330 封锁阳光大学 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这题还没整的很清楚。。先留着了
7-1
普通的模拟题 有一些字符串的读入
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
string s;
cin>>s;
if(s[0]=='.')
{
s[0]='C';
}
for(int i=1;i<s.length();i++)
{
if(s[i]=='.' and s[i-1]!='L')
{
s[i]='C';
}
else if(s[i]=='L')
{
if(s[i-1]=='C')
{
s[i-1]='.';
}
}
}
cout<<s;
}
7-3
一开始没想二分 想用贪心
但是出了些bug 于是下决心不死磕了
然后就想到这题的答案是有固定范围的
又是求最值
然后就写了二分答案果然很快就过了
还有judge函数里用到了之前想过的思路
就是对于一整个回合制移动的数组
可以转化为一个数据向不动数组的移动
所以 要多想 但不要死磕
#include<bits/stdc++.h>
using namespace std;
int a[100005];int n,m;
int judge(int x)
{
int xm=0;
for(int i=2;i<=n;i++)
{
xm+=x;
if(xm>a[i])
return 0;
}
return 1;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sort(a+1,a+n+1);
if(a[1]>m)
{
int t=a[1]-m;
for(int i=1;i<=n;i++)
{
a[i]-=t;
}
}
int left=0,right=a[n];
int mid;
while(left<=right)
{
mid=(left+right)/2;
if(judge(mid))
{
left=mid+1;
}
else
{
right=mid-1;
}
}
cout<<right;
}
7-3
首先是16进制的转化问题 得先搞明白十六进制的表示方法
原理大概是高精乘 和10进制竖式进位类似 只是改成16进位
然而我还没搞懂高精乘。。(高精加就已经够麻烦了x
7-4
球球不要再出链表了(x
我要是会一点也不至于一点也不会orz
7-5
二分
求导判断单调区间。。