目录
L3-1 二叉搜索树的结构(30) (二叉搜索树+string)
L3-2 森森快递(30) (贪心+线段树区间修改&区间查询)
L1-3 阅览室(20)
注意:开始时间可能为0,mp初始化需为-1
#include<bits/stdc++.h>
using namespace std;
const int N = 10005;
int n;
int nm,t1,h,m;
char c;
double cnt,sum;
int mp[N];
int main(){
scanf("%d",&n);
while(n--){
cnt=sum=0;
memset(mp,-1,sizeof(mp));//更新开始时间
while(1){
scanf("%d %c",&nm,&c);
scanf("%2d:%2d",&h,&m);
if(nm==0)break;
if(c=='E'){
if(mp[nm]==-1)continue;
else{
cnt++;
sum+=h*60+m-mp[nm];
mp[nm]=-1;
}
}else{
mp[nm]=h*60+m;
}
}if(cnt!=0)printf("%.lf %.lf\n",cnt,1.0*(sum+0.5)/cnt);
else printf("0 0\n");
}
return 0;
}
L1-6 整除光棍(20)
模拟除法,如111/23,1111/345,当11...1>x 时开始除法
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int maxn = 1e3 + 10;
int x,n,m=1;
int main(){
scanf("%d",&x);
while(m<x){
n++;m=m*10+1;
}while(1){
printf("%d",int(m/x));
n++;
if(m%x==0)break;
m=m%x*10+1;
}printf(" %d",n);
return 0;
}
L1-8 矩阵A乘以B(15)
注意:Ca和Rb要输出数字
#include<bits/stdc++.h>
using namespace std;
const int N = 1005;
int r1,c1,r2,c2,r3,c3;
int a[N][N],b[N][N],c;
int main(){
scanf("%d%d",&r1,&c1);
for(int i=1;i<=r1;i++){
for(int j=1;j<=c1;j++){
scanf("%d",&a[i][j]);
}
}
scanf("%d%d",&r2,&c2);
if(c1!=r2){
printf("Error: %d != %d",c1,r2);
return 0;
}
for(int i=1;i<=r2;i++){
for(int j=1;j<=c2;j++){
scanf("%d",&b[i][j]);
}
}
printf("%d %d\n",r1,c2);
for(int i=1;i<=r1;i++){
for(int j=1;j<=c2;j++){
c=0;
for(int k=1;k<=c1;k++){
c+=a[i][k]*b[k][j];
}printf("%d",c);
if(j!=c2)printf(" ");
}if(i!=r1)printf("\n");
}
return 0;
}
L2-2 重排链表(25)
a[N]:记录调整顺序前的链表每个节点的地址
b[N]:记录调整顺序后的链表每个节点的地址
输出时只需要知道当前节点的地址和下一节点的地址即可,数据可根据映射关系查询
注意:给出的n个节点可能不连续,所以更改顺序以及输出时用cnt做限制
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int idx,n;
struct node{
int data,nxt;
}mp[N];
int a[N],b[N];
int main(){
scanf("%d%d",&idx,&n);
for(int i=1;i<=n;i++){
int x;scanf("%d",&x);
scanf("%d%d",&mp[x].data,&mp[x].nxt);
}
int t=mp[idx].nxt;
int cnt=0;
a[++cnt]=idx;
while(t!=-1){
a[++cnt]=t;
t=mp[t].nxt;
}int front=1,rear=cnt;
cnt=0;
while(front<=rear){
b[++cnt]=a[rear--];
if(front<=rear)
b[++cnt]=a[front++];
}for(int i=1;i<=cnt;i++){
if(i!=cnt)
printf("%05d %d %05d\n",b[i],mp[b[i]].data,b[i+1]);
else
printf("%05d %d -1",b[i],mp[b[i]].data);
}
return 0;
}
L2-3 图着色问题(25) (DFS)
无向图DFS逐个搜索
注意:要求正好k个颜色
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int maxn = 1e3 + 10;
int n,m,k,x,y,q,vis[maxn],v[maxn];
vector<int>edge[maxn];
int f=1;
void dfs(int x){
vis[x]=1;
for(auto i:edge[x]){
if(v[i]==v[x]){
f=0;return;
}if(vis[i])continue;
//vis[i]=1;
dfs(i);
}
}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
edge[x].push_back(y);
edge[y].push_back(x);
}
scanf("%d",&q);
while(q--){
set<int>ss;
for(int i=1;i<=n;i++){
scanf("%d",&v[i]);
ss.insert(v[i]);
}if(ss.size()!=k){
printf("No\n");
continue;
}ss.clear();
f=1;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
dfs(i);
if(f)printf("Yes\n");
else printf("No\n");
}
return 0;
}
L3-1 二叉搜索树的结构(30) (二叉搜索树+string)
map中.count(x):查找键值x是否存在,存在返回1,不存在返回0
string中.find("s"):查找字符串中“s”是否出现,出现返回索引,未出现返回-1
sscanf(s.c_str()," "); string字符串输入
取对数:log(x)/log(2) 以2为底 x的对数
注意:需要判断题目给出的数值q1,q2是否在所给树中
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
int n,rt,t,m;
int a[N],v[N];
map<int,int>ani;
void add(int id,int x){
if(!v[id]){
a[id]=x,v[id]=1;
ani[x]=id;
return;
}if(x<a[id])add(id*2,x);
else add(id*2+1,x);
}
int main(){
scanf("%d%d",&n,&rt);
add(1,rt);
for(int i=2;i<=n;i++){
scanf("%d",&t);
add(1,t);
}
scanf("%d",&m);
int q1,q2;
while(m--){
q1=q2=0;
scanf("%d",&q1);
string ss;
getline(cin,ss);
//cout<<ss<<endl;
int f=0;
if(!ani.count(q1)){
printf("No\n");
continue;
}
if(ss.find("root")!=-1){
if(q1==rt)f=1;
}else if(ss.find("parent")!=-1){
sscanf(ss.c_str()," is the parent of %d",&q2);
if(ani.count(q2)&&int(ani[q1])==(ani[q2]/2))f=1;
}else if(ss.find("left")!=-1){
sscanf(ss.c_str()," is the left child of %d",&q2);
if(ani.count(q2)&&ani[q1]==ani[q2]*2)f=1;
}else if(ss.find("right")!=-1){
sscanf(ss.c_str()," is the right child of %d",&q2);
if(ani.count(q2)&&ani[q1]==ani[q2]*2+1)f=-1;
}
else{
if(ss.find("siblings")!=-1){
sscanf(ss.c_str()," and %d are siblings",&q2);
if(ani.count(q2)&&ani[q1]/2==ani[q2]/2)f=1;
}else if(ss.find("level")!=-1){
sscanf(ss.c_str()," and %d are on the same level",&q2);
if(ani.count(q2)){
int tp1=log(ani[q1])/log(2);
int tp2=log(ani[q2])/log(2);
if(tp1==tp2)f=1;
}
}
}if(f)printf("Yes\n");
else printf("No\n");
}
return 0;
}
L3-2 森森快递(30) (贪心+线段树区间修改&区间查询)
贪心,要想得到最大的运输重量,就要贪心地找最大的不想交的区间数目(因为如果相交,那么在这两段相交区间上运的货物就要共同占用公路的最大运送量)
按右端点升序排序,(如下图,取自: 区间覆盖问题 - 贪心_有n个互相不重叠的区间,问最大覆盖面积),用线段树维护区间的最小值,然后每选一个区间,把这个区间的最小值(tmp)查询一下,若tmp>0则可运,modify更新区间值减去x
val:节点i记录从i-1到i能运输的重量 ,更新为0
minv:记录子树最小运输重量
query:区间查询起点到终点最小值是否>0
modify:区间修改 t标记下放减去最小值
节点只需记录标记和最小值,无需info
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lson id*2,l,m
#define rson id*2+1,m+1,r
const int N = 1e5 + 5;
int n, q;
ll sum;
struct s_t{
int s,t,c;
bool operator<(const s_t&b)const{
//if(c!=b.c)return c<b.c;
if(t!=b.t)return t<b.t;
return s<b.s;
}
}a[N];
//val:节点i记录从i-1到i能运输的重量 ,更新为0
//minv:记录子树最小运输重量
//query:区间查询起点到终点最小值是否>0
//modify:区间修改 t标记下放减去最小值
//节点只需记录标记和最小值,无需info
struct node{
int t;
int minv;
}seg[N*4];
void update(int id){
seg[id].minv=min(seg[id*2].minv,seg[id*2+1].minv);
}
void settag(int id,int t){
seg[id].minv+=t;
seg[id].t+=t;
}
void pushdown(int id){
if(seg[id].t!=0){
settag(id*2,seg[id].t);
settag(id*2+1,seg[id].t);
seg[id].t=0;
}
}
void build(int id,int l,int r){
if(l==r){
scanf("%d",&seg[id].minv);
seg[l].t=0;
//printf("seg[%d].minv:%d\n",l,seg[l].minv);
return;
}int m=(l+r)/2;
build(lson);
build(rson);
update(id);
//printf("seg[%d].minv:%d\n",l,seg[l].minv);
}
int query(int id,int l,int r,int ql,int qr){
//printf("[%d,%d]\n",l,r);
//printf("seg[%d].minv:%d\n",id,seg[id].minv);
if(ql==l&&qr==r) {
return seg[id].minv;
}
pushdown(id);
int m=(l+r)/2;
if(qr<=m) return query(lson,ql,qr);
else if(ql>m)return query(rson,ql,qr);
else return min(query(lson,ql,m),query(rson,m+1,qr));
}
void modify(int id,int l,int r,int ml,int mr,int t){
if(ml==l&&mr==r){
settag(id,t);
return;
}pushdown(id);
int m=(l+r)/2;
if(mr<=m)modify(lson,ml,mr,t);
else if(ml>m)modify(rson,ml,mr,t);
else modify(lson,ml,m,t),modify(rson,m+1,mr,t);
update(id);
}
int main() {
scanf("%d %d", &n, &q);
build(1, 1, n-1);
for(int i=1;i<=q;i++){
int s,t;
scanf("%d%d",&s,&t);
if(s>t)swap(s,t);
a[i]=(s_t){s+1,t,t-s};
}sort(a+1,a+q+1);
for(int i=1;i<=q;i++){
int tmp=query(1,1,n-1,a[i].s,a[i].t);
//printf("a[%d].s:%d .t:%d tmp:%d\n",i,a[i].s,a[i].t,tmp);
if(tmp>0){
sum+=tmp;
modify(1,1,n-1,a[i].s,a[i].t,-tmp);
}
}printf("%lld",sum);
return 0;
}