存图+周赛

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

二分

求导判断单调区间。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值