比赛题目(近期)整理和知识点汇总(初学图论)

      还是先整理下题目

走格子

在平面上有n*n大小的正方形,定义正方形左下角坐标是(1,1),右下角坐标是(n,1)现在A君在左下角,他的初始方向是向右,他要在正方形内走m步当A君碰到边界或者已经走过的格子时,他便会逆时针转90°继续走,直到走完m步。现在给你两个整数n和m,请算出走完m步后A君的坐标。

    dfs一下

const int maxn=3005;
int mp[maxn][maxn];
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1},n,m;
int judge(int x,int y)
{
    if(x>=1&&y>=1&&x<=n&&y<=n)
    {
        if(mp[x][y]==0)return 1;
    }
    return 0;
}
int f=0;
void dfs(int x,int y,int d,int ans)
{
    mp[x][y]=1;
    if(ans>=m)
    {
        printf("%d %d\n",x,y);
        f=1;
        return;
    }
    int xx=x+dx[d];
    int yy=y+dy[d];
    if(judge(xx,yy)) dfs(xx,yy,d,ans+1);
    else dfs(x,y,(d+1)%4,ans);
}
int main()
{
    scanf("%d%d",&n,&m);
    dfs(1,1,0,0);
    return 0;

}

求值2

给出n求Ans

Ans = 0; 

For(inti = 1; i <= n; i++) 
    For(int v = 0; v <= n; v++) 

         Ans = (Ans + C(i, v) * C(i, v)) % 998244353;

这道题需要公式推导一下,

1,C(n,1)+C(n,2)+...C(n,n)=2^n;

2,C(n,1)+2*C(n,2)+3*C(n,3)+....n*C(n,n)=n*2^(n-1);

3,C(a,0)C(b,n)+C(a,1)C(b,n-1)+...C(a,n)C(b,0)=C(a+b,n) , n=min(a,b);

4,(C(n,0)^2)+(C(n,1)^2)+...(C(n,n)^2)=C(2n,n)。

定理4是用3推出的,3是直接推下。具体证明看《概率论与数理统计教程》(第二版)茆诗松 30页课后题

跳格子

sum 个格子排成一排,每次可以往前跳 1-n 格,往回跳 1-m 格,而且在往回跳的时候只能跳在往前跳时踩过的格子。现在,在格子上跳,问跳到最后一个格子上最后又跳回第一个格子之前的方案数 mod 233333333。注意:只能一直向前跳,跳到最后一个格子,然后再往回跳,跳回第一个格子之前。

这道题我还是得继续琢磨琢磨。。。。

官方题解:

从最后一个格子跳回第一个格子之前可以看作是从一个格子之前跳到最后一个格子
所以题意就变成了
跳两次
第二次跳必须踩在第一次跳的格子上
则第二次跳的格子的集合必定是作为第一次跳的格子的子集
我们考虑枚举枚举第二次跳的距离i
搜索有第一次跳的长度为i的方案数vi
然后有递推式f[n]=f[n-1]*v1+f[n-2]*v2+..+f[n-m]*vm

递推即可

const int N=4e5+5;
const int M=15;
const int mod=233333333;
int f[M],dp[N];
int main()
{
    int n,m,sum,T;
    scanf("%d",&T);
    while(T--){
        memset(f,0,sizeof(f));
        memset(dp,0,sizeof(dp));
        scanf("%d%d%d",&sum,&n,&m);
        f[0]=1;
        for(int i=1;i<=m;i++){
            for(int j=1;j<=i&&j<=n;j++){
                f[i]=(f[i]+f[i-j])%mod;
            }
        }
        dp[0]=1;
        for(int i=1;i<=sum;i++){
            for(int j=1;j<=m&&j<=i;j++){
                dp[i]=(dp[i]+1ll*dp[i-j]*f[j]%mod)%mod;
            }
        }
        printf("%d\n",dp[sum]);
    }
    return 0;

}

Educational Codeforces Round 45 (Rated for Div. 2) C.Bracket Sequences Concatenation Problem

题意:给出n组括号组合,定义')'+'('=')('。问有多少对stra+strb合法。

思路:处理每一行括号组合,遇到'('就+1,遇到')'就-1,当然还要用栈处理掉不合法的情况')(',就是排除无论如何都没法组合的情况,然后用map记录每个合法的组的值,最后找匹配就可以了。

map<ll,ll>mp1;
map<ll,ll>mp2;
map<ll,ll>::iterator it;
stack<ll>k;
ll n;
char s[300005];
int main()
{
    ll len,t;
    int flag=0;
    mp2.clear();
    mp1.clear();
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s);
        len=strlen(s);
        t=0;
        for(int j=0;j<len;j++)
        {
            if(s[j]=='(') k.push(1);
            else if(s[j]==')')
            {
                if(!k.empty()) k.pop();
                else t++;
            }
        }
        if(t!=0&&!k.empty()) {while(!k.empty()) k.pop(); continue;}//此时无论是')('类似无论怎样都不合法
        else if(t==0&&!k.empty()) mp1[k.size()]++;
        else if(t!=0&&k.empty()) mp2[(-t)]++;
        else if(t==0&&k.empty()) mp1[0]++;
        //cout<<t<<" "<<k.empty()<<endl;
        while(!k.empty()) k.pop();
    }
    ll ans=0;
    for(it=mp1.begin();it!=mp1.end();it++)
    {
        if(it->first==0)
        {
            ll r=it->second;
            ans=ans+r*r;
        }
        else
        {
            ll r=it->first;
            ll q;
            q=-r;
            ll w=mp2[q];
            ans=ans+w*(it->second);
        }
    }
    cout<<ans<<endl;

}

零碎的整理图论,还是回来再专门整理汇总吧

还正在看,一边啃运筹学课本一边瞎看博客中

下面来自:https://blog.csdn.net/u013514182/article/details/42281479

求连通分量

int current_cc,cc[maxn],vis[maxn];  
vector<int> g[maxn];  
void dfs(int u)
{  
    vis[u]=1;cc[u]=current_cc;  
    for(int i=0;i<g[u].size();i++)
{  
        int v=g[u][i];  
        if(!vis[v]) dfs(v);  
    }  
}  
  
void find_cc(int n)//求连通分量
{
    current_cc=0,mem(vis,0);  
    for(int u=1;u<=n;u++) if(!vis[u]) { current_cc++;dfs(u); }  

}  

.判定一个图是否为二分图&&无向图构造二分图
二分图定义:对于无向图G=<V,E>,如果可以把点集分为互不相交的两部分,即X和Y=V-X,使得每一条边的其中一个端点在X中,另一个端点在Y中,则称该图是二分图


非连通图是二分图 <=> 每个连通分量都是是二分图
int color[maxn];  
vector<int> g[maxn];  
bool bipartite(int u){  
    for(int i=0;i<g[u].size();i++){  
        int v=g[u][i];  
        if(color[v]==color[u]) return false;  
        if(!color[v]){  
            color[v]=3-color[u];  
            if(!bipartite(v)) return false;  
        }  
    }  
    return true;  
}  
  
bool judge_bipartite(){  
    for(int i=1;i<=n;i++)  
        if(!color[i]){  
            color[i]=1;  
            if(!bipartite(i)) return false;  
        }  
    return true;  



求割点/割顶(cut_vertex/articulation vertex)和桥(bridge)


割点定义:删除该点后,原图的连通分量数增加。对于连通图,就是删除该点后原图不再连通的点。


桥的定义:删除该边后,原图的连通分量数增加。对于连通图,就是删除该边后原图不在连通的边。
int dfs_clock=0,low[maxn],pre[maxn],is_cut[maxn],is_bridge[maxn][maxn];  
vector<int> g[maxn];  
  
void dfs(int u,int fa){  
    low[u]=pre[u]=++dfs_clock;//u一开始最远返向边指向自己  
    int child=0;  
    for(int i=0;i<g[u].size();i++){  
        int v=g[u][i];  
        if(!pre[v]){  
            child++;//记录孩子个数  
            dfs(v,u);  
            low[u]=min(low[u],low[v]);//u子树(除u外)的反向边  
            if(low[v]>=pre[u]) is_cut[u]=1;//u是割点  
            if(low[v]>pre[u]) is_bridge[u][i]=1;//u出发的第i条边是桥  
        }  
        else if(pre[v]<pre[u]&&v!=fa) low[u]=min(low[u],pre[v]);//u自己的反向边  
    }  
    if(fa<0&&child==1) is_cut[u]=0;//对根节点进行特判  
}  
  
void find_cutvertex_bridge(int n){  
    mem(is_cut,0),mem(is_bridge,0),mem(pre,0);  
    for(int i=1;i<=n;i++) if(!pre[i]) dfs(i,-1);  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: PLC编程入门基础知识点,对于初学者来说是非常必要的。以下是几个重要的知识点: 1. PLC基本原理:了解PLC是什么以及其在工控系统中的作用。PLC(可编程逻辑控制器)是一种用于自动化控制的硬件设备,它能够根据预先编写的程序控制和监控各种设备和过程。掌握PLC的基本原理是理解PLC编程的基础。 2. 编程语言:学习PLC编程语言是非常重要的。常用的PLC编程语言包括梯形图、指令列表和函数块图。梯形图是最常见的一种编程语言,类似于电气图形符号,易于理解和编写。指令列表和函数块图则更适合编写复杂的控制程序。 3. 输入/输出和数据类型:学习如何配置和使用PLC输入/输出模块,并了解不同的输入/输出类型。此外,掌握不同的数据类型,如位、字节、整数和浮点数,有助于正确操作和处理数据。 4. 逻辑和运算:学习常用的逻辑运算符如与、或、非等,并了解如何使用这些运算符编写逻辑条件。学习如何使用数学运算符和其他运算符进行算术和比较操作也是非常重要的。 5. 接口和通信:了解PLC与其他设备和系统的接口和通信方式。学习如何配置和编程串行接口、以太网接口、通信协议等,以实现与其他设备的数据交换和通信。 6. 故障排除和调试:掌握故障排除和调试的基本方法,以保证编写的控制程序能够正确运行。学会使用PLC编程软件的调试工具,如在线监视、硬件调试等。 以上是PLC编程入门的基础知识点,初学者应该掌握这些内容,以便能够进行基本的PLC编程和控制工作。当然,PLC编程是一个广阔而复杂的领域,需要不断学习和实践才能掌握更高级的技能。 ### 回答2: PLC编程入门基础知识点主要包括以下几个方面,对初学者来说,这些知识是必不可少的。 1. PLC基本概念:了解PLC是什么以及它的作用。PLC是可编程逻辑控制器的简称,主要用于控制和监测工业过程中的设备和机器。了解PLC的基本工作原理和使用方式对于学习编程非常重要。 2. 电气基础知识:掌握基本的电路知识,了解PLC的电气连接方式和电气元件的作用,例如继电器、传感器和执行器等。 3. Ladder Diagram(LD)符号的学习:LD是最常用的PLC编程语言。初学者应该熟悉不同的LD符号及其含义,如输入输出符号、逻辑门符号和定时器/计数器符号等。 4. 逻辑运算和控制:了解逻辑运算的基本原理和常用的逻辑门(与门、或门、非门等),还应掌握控制的基本原理,如常闭/常开控制、电磁阀控制和时序控制等。 5. 输入/输出配置:学习如何配置PLC输入/输出模块和信号输入/输出。了解输入/输出的类型,如数字信号、模拟信号和特殊信号等。 6. PLC指令:学习PLC的基本指令,如传送指令、比较指令、运算指令和数据处理指令等。这些指令是编写PLC程序的基础。 7. 调试与故障排除:学习如何调试PLC程序和排除故障。初学者应该了解PLC调试工具和常见的故障排除方法。 总之,以上是PLC编程入门的基础知识点。初学者应该全面掌握这些知识,为进一步学习和应用PLC编程打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值