A-典型的追击问题,较多的坑点,回游有很多种情况,注意分类

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main(){
  double l,k,a,b;
  cin>>l>>k>>a>>b;
  printf("%.2f\n",l/b-l/a);
  return 0;
}
View Code

B-水题,模拟就行

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int a[1000006];
int main(){
  int n;
  while(~scanf("%d",&n)){
    for (int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int flag=2;
    int cnt=0;
    for (int i=1;i<n;i++){
        if (flag==2){
            if (a[i]<a[i+1]){
                flag=1;
            }
            if (a[i]>a[i+1]){
                flag=3;
            }
            continue;
        }
        if( flag==1 &&a[i]>a[i+1]){
            flag=3;
            cnt++;
            continue;
        }
        if ( flag==3 && a[i]<a[i+1]){
            flag=1;
            continue;
        }
    }
    printf("%d\n",cnt);
  }
  return 0;
}
View Code

C-典型的树的直径问题-两遍DFS

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define INF 1e9+7
using namespace std;
const int MAXN = 2000000;
const int MAXM = 2000000;
int n,m;
struct EDGE
{
    int v,next,w;
}edge[MAXN];
int head[MAXN],e;
int q[MAXN],vis[MAXN],d[MAXN];
void init()
{
    e=0;
    memset(head,-1,sizeof(head));
}
void add(int u,int v,int w)//链式前向星部分
{
    edge[e].v=v;
    edge[e].w=w;//权重
    edge[e].next=head[u];//下一条边
    head[u]=e++;//u为节点边的头节点
}
void bfs(int src)
{
    for(int i=1;i<=n;i++)vis[i]=0,d[i]=INF;
    int h=0,t=0;
    q[t++]=src;
    vis[src]=1;
    d[src]=0;
    while(h<t)
    {
        int u=q[h++];
        for (int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            int w = edge[i].w;
            if (d[u]+w<d[v]){
                d[v]=d[u]+w;
                if (!vis[v])
                {
                    q[t++]=v;
                    vis[v]=1;
                }
            }
        }
    }
}
int main(){
 int u,v,w;
 char k;
 scanf("%d",&n);
 init();
 for(int i=1;i<=n-1;i++)
 {
     scanf("%d%d",&u,&v);
     add(u,v,1);
     add(v,u,1);
 }
 bfs(1);
 int pos=-1,mx=-1;
 for (int i=1;i<=n;i++)
    if (d[i]>mx)
 {
     mx=d[i];
     pos=i;
 }
 bfs(pos);
 mx=-1;
 for (int i=1;i<=n;i++)
    if (d[i]>mx)mx=d[i];
 printf("%d\n",mx+1);
 return 0;
}
View Code

D-水题

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<map>
using namespace std;
char a[1000006];
int pre[1000006];
int main(){
  int n,m;
  map<char,int> p;
  while(~scanf("%d%d",&n,&m)){
    p.clear();
    scanf("%s",a);
    int lena=strlen(a);
    for (int i=0;i<lena;i++){
       p[a[i]]++;
       pre[i+1]=p[a[i]];
    }
    int tmp;
    for (int i=1;i<=m;i++){
        scanf("%d",&tmp);
        printf("%d\n",pre[tmp]);
    }
  }
  return 0;
}
View Code

E-很好的简单搜索

#include<iostream>
#include<stdio.h>
#include<string.h>
#define rep(i,j,k) for(int i=j;i<=k;++i)
using namespace std;
int vis[1005][1005];
int dx[10]={0,0,1,-1,1,-1,1,-1};
int dy[10]={1,-1,0,0,1,-1,-1,1};
int n,m;
bool dfs(int x,int y,int z){
    vis[x][y]=z;
    int xx,yy;
    int cnt;
    for (int i=0;i<=7;i++){
        xx=x;
        yy=y;
        if(i%2==0)
        cnt=1;
        for (int j=0;j<=3;j++){
           xx=xx+dx[i];
           yy=yy+dy[i];
        //   cout<<xx<<" "<<yy<<" ";
           if (xx<1 || yy<1 || xx>n || yy>n || vis[xx][yy]!=z){
            break;
           }
           cnt++;
        }
        if (cnt>=5){
            return 1;
        }
    }
    return 0;
}
int main()
    {
 
        while(~scanf("%d %d",&n,&m))
        {
 memset(vis,-1,sizeof(vis));
        int id=-1,x,y;
        rep(i,1,m)
        {
            scanf("%d %d",&x,&y);
            if(id==-1)
            {
                if(dfs(x,y,i%2))
                    id=i;
            }
        }
         if(id==-1)
            printf("UNK %d\n",m);
        else if(id%2)
            printf("HtBest %d\n",id);
        else
            printf("WHZ %d\n",id);
        }
        return 0;
    }
View Code

F-树状数组,把维护区间和改为维护区间乘积就行

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int dx[10]={1,-1,1,-1,0,0,-1,1};
int dy[10]={1,-1,0,0,-1,1,1,-1};
int vis[1004][1004];
int n,m;
bool dfs(int x,int y,int z){
   vis[x][y]=z;
   int xx,yy,cnt;
   for (int i=0;i<=7;i++){
      xx=x;
      yy=y;
      if (i%2==0){
        cnt=1;
      }
      for(int j=0;j<=3;j++){
         xx+=dx[i];
         yy+=dy[i];
         if (xx<1 || yy<1 || xx>n || yy>n || vis[xx][yy]!=z){
            break;
         }
         cnt++;
      }
      if (cnt>=5){
        return 1;
      }
   }
   return 0;
}
int main()
{
    while(~scanf("%d%d",&n,&m)){
        int x,y;
        int flag=-1;
        memset(vis,-1,sizeof(vis));
        for (int i=1;i<=m;i++){
           scanf("%d%d",&x,&y);
           if (flag==-1){
              if (dfs(x,y,i%2)){
                  flag=i;
              }
           }
        }
        if (flag==-1){
            printf("UNK %d\n",m);
        }else if (flag%2==0){
            printf("WHZ %d\n",flag);
        }else if (flag%2==1){
            printf("HtBest %d\n",flag);
        }
    }
    return 0;
}
View Code

G-重载set内部排序就行

#include<bits/stdc++.h>
using namespace std;
int m,k;
struct cmp
{
    bool operator() (int a,int b)
    {
        if(abs(a-b)<=k) return false;
        return a<b;
    }
};
set<int,cmp>s;
int main()
{
    scanf("%d%d",&m,&k);
    int x;
    char op[8];
    while(m--)
    {
        scanf("%s%d",op,&x);
        if(op[0]=='a')
        {
            if(s.find(x)==s.end())
            {
                s.insert(x);
            }
        }
        else if(op[0]=='d')
        {
            s.erase(x);
        }
        else
        {
            if(s.find(x)!=s.end()) printf("Yes\n");
            else printf("No\n");
        }
    }
    return 0;
}
View Code

H-裸题最小生成树

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
struct node{
  int u,v,w;
}a[500006];
int p[100006];
int r[100006];
int n,m;
int find(int x){return p[x] == x ? x : p[x] = find(p[x]);}//不是根节点
int cmp(node x,node y)
{
    return x.w<y.w;
}
int Kruskal(){
        int ans=0;
        int num=0;
        for (int i=1; i<=n; i++)p[i]=i;
        sort(a+1,a+1+m,cmp);
        for (int i=1; i<=m; i++)
        {
            int x=find(a[i].u);//出发点的根节点
            int y=find(a[i].v);//到达点的根节点
            if (x!=y)//不是一个根节点
            {
                ans+=a[i].w;//连接
                p[x]=y;//y是x的父亲节点
                num++;//建立好了n-1条边
            }
            if (num==n-1){
                break;
            }
        }
    return ans;
}
int main()
{
    int tmp1,tmp2,tmp3;
    while(~scanf("%d%d",&n,&m))
    {
        for (int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
        }
        printf("%d\n",Kruskal());
    }
    return 0;
}
View Code

I-裸的最短路问题

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
int a[1005][1005];//邻接表点
ll d[1005];//到出发点距离
int vis[10005];//是否访问过
int n,m,s,t;
void Dijkstra(int st)
{
    int minn;//最小值
    int p;//
    for (int i=1; i<=n; i++)d[i]=a[st][i];//初始化 每个点到出发点的距离
    vis[st]=1;
    d[st]=0;
    for (int i=1; i<=n-1; i++)
    {
        minn=INF;
        for (int j=1; j<=n; j++)
            if (!vis[j] && minn>d[j]) //如果未被访问过 并且到目前点的距离比min更小
            {
                p=j;//更新边
                minn=d[j];//更新新的距离
            }
            //循环下来 我们找到了最小的一条边
        vis[p]=1;//走过
        for (int j=1; j<=n; j++)
        {
            if (!vis[j] && d[p]+a[p][j]<d[j])
                d[j]=d[p]+a[p][j];
        }
    }
    if (d[t]!=INF)
        printf("%d\n",d[t]);
    else
        printf("-1\n");
}
  
int main()
{
    int tmp1,tmp2,tmp3;
    while (~scanf("%d%d%d%d",&n,&m,&s,&t))
    {
        memset(vis,0,sizeof(vis));
        memset(a,0x3f,sizeof(a));
        for (int i=0; i<m; i++)
        {
            scanf("%d%d%d",&tmp1,&tmp2,&tmp3);
            if (tmp3<a[tmp1][tmp2]){
            a[tmp1][tmp2]=tmp3;
            a[tmp2][tmp1]=tmp3;
            }
        }
        Dijkstra(s);
    }
    return 0;
}
View Code

J-一阶线性递推+逆元/矩阵快速幂

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#define ll long long
using namespace std;;
const ll mod = 1e9+7;
ll pow(ll a,ll b)
{
    ll ans = 1;
    while(b)
    {
        if (b&1)
        {
            ans = ans*a%mod;
        }
        a = a*a%mod;
        b/=2;
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(0);
    ll n,k,p;
    ll ans=0;
    while(~scanf("%lld%lld%lld",&n,&k,&p))
    {
        if (k==1)
        {
             ans=(n*(n-1)%mod/2*p+n)%mod;
             printf("%lld\n",ans);
        }
        else
        {
            ll inv=pow(k-1,mod-2);
            ans=(1+p*inv%mod)%mod*((pow(k,n)-1+mod)%mod)%mod*inv%mod;
            ans=(ans-p*inv%mod*n%mod+mod)%mod;
            printf("%lld\n",ans);
        }
    }
    return 0;
}
View Code