文章目录
The Third Week
反思是知识的沉淀,智慧的启示,思维的升华。——泰戈尔
一、前言
周一打了牛客,额,我是队长,但实在是不理解三个人该怎么互相配合着打信息竞赛,幸好是一人一台电脑,大家各自选了几个擅长的模块的题再写,但配合也并不好,最后只ac了3题,大家都有点气馁。插句题外话,那个很厉害的第一去打div1了好像,还是超厉害,向他致敬。
周三又打了排位赛,做了这么多天的题目,这些题目属于我想一会能想出来的类型,还挺喜欢这个难度的,毕竟一直做不出来也是很有挫败感的,抽时间补题。另外下一次就又是牛客了。
新年快乐
周五排位赛,就我自己来说还算满意吧。
二、算法
1.差分优化
<1>(洛谷P3406)
一道蛮经典的差分,但我总感觉有点dp的意思,差分跟前缀和挺相近的,上周学完前缀和之后就去看差分了。
题解:
题目较长,大意是要去m个城市,每俩个城市间可以选择购买纸质单程票,或者买卡充值,可重复通过一个城市,问最少花多少钱。
剩下的就很简单了,一个差分的板子,可以用二维但是还没学会。
代码:
#include<bits/stdc++.h>
using namespace std;
int main() {
int n,m;
cin>>n>>m;
long long int p[100010];
long long int q[100010]; //记录每段路的经过次数
for(int i=1;i<=m;i++)cin>>p[i];
int a[100010],b[100010],c[100010];
int cf[100010]; //用于差分数组
for(int i=1;i<=n-1;i++){
cin>>a[i]>>b[i]>>c[i];
}
for(int i=1;i<=m-1;i++){ //差分
if(p[i]<=p[i+1]){
cf[p[i]]+=1;
cf[p[i+1]]-=1;
}
else {
cf[p[i+1]]+=1;
cf[p[i]]-=1;
}
}
long long int sum=0;
for(int i=1;i<=n-1;i++){
q[i]=q[i-1]+cf[i]; //前缀和
sum+=min(a[i]*q[i],c[i]+b[i]*q[i]); //取价格小的情况
} //贪心?
cout<<sum;
return 0;
}
2.背包
<1>(CF Gym102897F)
01背包+完全背包
3.拓扑排序
在一个有向图中找一个拓扑序列的过程称作拓扑排序。
先行关系具有可转递性,拓扑序列不是唯一的,甚至有可能不存在。
<1>(AOV)
事实上我只能勉强听懂并跟着up主走一遍
代码:
#include<bits/stdc++.h>
using namespace std;
typedef struct node{
int adj;
struct node *nextarc;
}arcNode;
typedef struct{
string data;
arcNode *firstArc;
}vexNode;
typedef struct{
int n,e;
vexNode adjlist[20];
}AdjGraph;
void createGraph(AdjGraph &g){
cin>>g.n>>g.e;
for(int i=0;i<g.n;i++){
cin>>g.adjlist[i].data;
g.adjlist[i].firstArc=NULL;
}
int u,v;
for(int i=0;i<g.e;i++){
cin>>u>>v;
arcNode *s=new arcNode;
s->adj=v;
s->nextarc=g.adjlist[u].firstArc;
g.adjlist[u].firstArc=s;
}
}
int TopoSort(const AdjGraph &g){
stack<int>s;
int indegree[20]={0};
arcNode *p;
for(int i=0;i<g.n;i++){
p=g.adjlist[i].firstArc;
while(p){
indegree[p->adj]++;
p=p->nextarc;
}
}
for(int i=0;i<g.n;i++){
if(indegree[i]==0)s.push(i);
}
int count =0;
int u;
while(!s.empty()){
u=s.top();
s.pop();
count++;
p=g.adjlist[u].firstArc;
}
if(count<g.n)return 0;
else return 1;
}
int main() {
AdjGraph g;
createGraph(g);
if(TopoSort(g)==0)
cout<<"\n";
else cout<<"\n";
return 0;
}
<2>(CF Gym102897G)
啥也不是没写出来,真的服气
1.拓扑排序(dfs)
2.度的思想
4.DP
<1>(洛谷P1359)
过年的时候帮朋友看的一道dp题,刚好巩固一下,就放上来了
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[205][205];
int n;
int dp[205];
cin>>n;
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
cin>>a[i][j];
dp[i]=1e9;
}
}
for(int i=n-1;i>=1;i--){
for(int j=i+1;j<=n;j++){
dp[i]=min(dp[i],a[i][j]+dp[j]);
}
}
cout<<dp[1];
return 0;
}
5.二分算法
二分查找一直有一个很大的问题就是mid的+1,-1,特意去学习了一下。
int L=-1,R=n;
while(L+1!=R)
{
int mid=L+R>>1;
if(check()) L=mid;
else R=mid;
}
6.其它
<1>(CF Gym102897D)
这题只有十行代码…那为什么我特意弄了个其它放这题呢?因为我当时俩个小时没看明白这题…但是好多人都ac了,不懂但大受震撼,后来都想放弃了,就随便交了一次忽然脑子就开窍了…引以为戒,似难非难的题很多人做出来了总有它的道理。太简单了直接放代码了。
代码:
#include<bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int n;
cin>>n;
string s[n];
int t=0;
for(int i=0;i<n;i++){
cin>>s[i];
t+=s[i].length();
}cout<<t<<endl;
return 0;
}
<2>(CF Gym102899K)
这题说实在的,当时确实不太会做行列式 了,题目所给的计算方法我也不会,真没办法做了,后来去对着线性代数做行列式,代码编写不难。
题解:
题意即题面,问题在于看不懂note的计算公式,直接当行列式算的。
代码:
#include<bits/stdc++.h>
using namespace std;
int main() {
int l,r;
cin>>l>>r;
int ans;
int min=10000000;
for(int x=l;x<=r;x++){
int value=1170*(21-x)+41194-(21-x)*728-52504;
if(value<min){
min=value;
}
}
cout<<min<<endl;
return 0;
}
三、总结
这周过年很懈怠,加油。很多算法都只是大概学了一下,不知道能不能很好的运用。这次最大的问题在很多题目看不出它本质,其它里面的俩道题都是这种情况,本来应该做的更好的。也许可以考虑做一些比较偏的题,不考算法板子考思维的那种。