其实也算正式学习的第一天了。
信息学
今天先复习了一下最小生成树。
第一道:最小生成树模板
模板题没啥好讲的
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct edge{
int u,v,w;
};
int n,m;
//int ans;
int p[5005];
edge e[200005];
int find(int xx){
return xx==p[xx]?xx:p[xx]=find(p[xx]);
}
int cmp(edge a,edge b){
return a.w<b.w;
}
int kruskal(){
int ans=0;
sort(e,e+m,cmp);
for(int i=1;i<=n;i++){
p[i]=i;
}
for(int i=0;i<m;i++){
int xx=find(e[i].u),yy=find(e[i].v);
if(xx!=yy){
p[xx]=yy;
ans+=e[i].w;
}
}
return ans;
}
int vis[5005];
int main(){
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
vis[e[i].u]=vis[e[i].v]=1;
}
for(int i=1;i<=n;i++){
if(vis[i]==0){
printf("orz");
return 0;
}
}
printf("%d",kruskal());
return 0;
}
第二道:FBI树
不知道在这道题能不能用最下生成树做,我在洛谷找最小生成树时找到的。
如果不能,就当它是乱入的。
毕竟也是一道经典题,有可能考的,所以就随手做了一下。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m;
int num[1030];
int tree[4120];
int build(int rt,int l,int r){
if(l==r){
return tree[rt]=num[l]==0?-1:1;
}
int mid=(l+r)>>1;
return tree[rt]=(build(rt<<1,l,mid)+build(rt<<1|1,mid+1,r))/2;
}
void print(int rt){
if(tree[rt]==10){
return;
}
print(rt<<1);
print(rt<<1|1);
if(tree[rt]==1){
printf("I");
}else if(tree[rt]==0){
printf("F");
}else{
printf("B");
}
}
int main(){
for(int i=0;i<4120;i++){
tree[i]=10;
}
scanf("%d\n",&n);
m=(int)pow(2,n);
for(int i=1;i<=m;i++){
char c;
scanf("%c",&c);
num[i]=c-'0';
}
build(1,1,m);
print(1);
return 0;
}
没有什么可讲的。
第三题:River Jumping
这是洛谷七月赛的一道题。
显然不是最小生成树。
这道题并不是非常难。
首先我们排除一点,就是如果出现“死亡三石组”,那么一定是NO。
什么是“死亡三石组”?
就是指两块距离小于s的石头中还夹着一块石头,那么这三块石头构成“死亡三石组”。
为什么不行是很显然的。
接下来就是贪心进行跳,如果无法调到对岸,或是返回时有一块石头无法到达,就NO,其他情况就YES,然后输出结果即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,s;
int pos[100005];
int ans[100005];
int main(){
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=m;i++){
scanf("%d",&pos[i]);
}
pos[0]=0;
pos[m+1]=n;
for(int i=0;i<m;i++){
if(pos[i+2]-pos[i]<s){
printf("NO");
return 0;
}
}
int cur=0;
int ind=0;
for(int i=1;i<=m+1;i++){
if(pos[i]-cur<s){
continue;
}
cur=pos[i];
pos[i]=-1;
ans[ind]=i;
ind++;
}
if(cur!=n){
printf("NO");
return 0;
}
for(int i=m;i>=0;i--){
if(pos[i]!=-1){
if(cur-pos[i]<s){
printf("NO");
return 0;
}else{
cur=pos[i];
ans[ind]=i;
ind++;
}
}
}
printf("YES");
printf("\n%d",ans[0]);
for(int i=1;i<m+2;i++){
printf(" %d",ans[i]);
}
return 0;
}
好,到现在为止,你可能已经看出我的不专心了。
额,无所谓了,反正在做题,又不是在打游戏。
下面我们来复习线段树。
掏出自己的博客:谈笑风生线段树
其实好像没什么值得复习的,记得挺清楚的。
我们还是来看看神奇的倍增吧!
但是刚刚遇到了一个问题,那就是long double的问题。
我发现用printf输出long double的变量,是无法输出的。
所以,大家一定要记住,long double一定要用cout去输出。
当然,这个也尽量少用。
没时间了,倍增就明天看吧!
数学
数学今天就水了些题目!
物理
物理今天看了Y-△变换、对称电路、惠斯通电桥、电流分布法。
总结
今天效率太低了,明天要加油