【10.26测试】

本文探讨了字符串权值最大化的算法实现及视线判断问题的解决方案,包括字符串子串权值计算方法与视线判断中的数学和物理原理应用。

T1

【问题描述】
定义新字符串的权值计算方法。一个字符串由小写字母组成,字符串的权值被定义为其中出现次数最多的字符的次数减去出现次数最少的字符的次数。(注意,在讨论出现最少的字符的时候,该字符必须至少出现一次)现在给你一个字符串,这个字符串的所有子串中权值最大的权值是多少?
【输入格式】
第一行一个整数n,代表字符串的长度。
接下来一行n个小写字母,代表该字符串。
【输出格式】
一行一个整数代表答案。
【样例输入】
10
aabbaaabab
【样例输出】
3
【数据范围与规定】
对于30%的数据, 1 ≤n ≤ 100
对于60%的数据, 1 ≤ n ≤ 1000
对于100%的数据, 1 ≤ n ≤ 10^6

思路

先扔出来一组自造数据
10
aaabaaaaab
一开始做题直接懵那去了,样例能过但是过不了这个(其实能过,但是非常zz的以为这个答案是8而不是7.。。不知道当时的脑回路是怎么个构造)

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<string>
using namespace std;
const int sz = 1000010;
const int size = 26;
const int N = 1500;
const int inf = 214748364;
#define ri register int
inline void rd(int &x){
    x=0;bool f=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    if(f) x*=-1;
}
char fu[sz];
int n,t[sz],ans,num;
int ed[sz],f[N][N],dis[N][N];
inline int check(int x,int y){
    return x==y;
}
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    rd(n);scanf("%s",fu+1);
    for(ri i=1;i<=n;++i)
    {
        num=fu[i]-'a',t[num]++;
        ed[num]=i;
        for(ri j=0;j<size;++j)
        {
            if(j!=i&&t[j])
            ans=max(ans,max
                (t[num]-t[j]-check(ed[j],f[num][j])-dis[num][j],
                    t[j]-t[num]-check(ed[j],f[j][num])-dis[j][num]));
        }
        for(ri k=0;k<size;++k)
        {
            if(dis[num][k]>t[num]-t[k])
            {
                dis[num][k]=t[num]-t[k];
                f[num][k]=i;
            }
            if(dis[k][num]>t[k]-t[num])
            {
                dis[k][num]=t[k]-t[num];
                f[k][num]=i;
            }
        }
    }
    cout<<ans<<'\n';
    fclose(stdin);
    fclose(stdout);
    return 0;
}
/*
10
aabbaaabab
*/

T2

这里写图片描述
这里写图片描述

【输出格式】
如果 Hja 站在原地能看到 Yjq,则输出”YES”,否则输出”NO”。
【样例输入 1】
-1 3
1 3
0 2 0 4
0 0 0 1
【样例输出 1】
NO
【样例输入 2】
0 0
1 1
0 1 1 0
-100 -100 -101 -101
【样例输出 2】
NO
【样例输入 3】
0 0
1 1
0 1 1 0
-1 1 1 3
【样例输出 3】
YES
【样例输入 4】
0 0
10 0
100 100 101 101
1 0 3 0
【样例输出 4】
YES
【数据规模与约定】
对于100%的数据, 所有坐标均为绝对值不超过104的整数。输入的线段不会
退化成点,且两条线段没有交点。 Hja 和 Yjq 的位置不同,且不在任何一条线段

思路

真是个,,,良心题目?输出YES有46分,NO则是54分(刷脸机?)自带数学与物理美感的题目emmmmm,以下分析用M代表镜子,W代表墙
这里写图片描述
我们考虑多种情况,首先我们将线段看成直线,两条直线分别代表墙和目光
这样对于右边的图来说,如果O为AB和CD交点,那么AB和CD想要避免相交就必须满足对于每一条线段的两端都要在交点的同侧才可以做到不相交,即到对方;而分隔在两侧是绝对看不到对方只能看墙的
这个判断我们可以做到先求出直线的方程(都是一次函数 y=kx+b)然后我们找斜率k的关系,判断求解

那么具体是如何做呢?如果两人在镜子同一侧,并且ST连线穿过了墙(不可能直接看到),我们需要对镜贴花黄【划掉划掉】研究下
这里写图片描述
根据美妙的数学和物理原理,我们做S对于M的对称点S’ 那么S’T的连线就是目光,可以理解为橙色的和红实线是目光,而红虚线是假象目光线(数学上经常用啊什么的)
设交点为P,那么分析如果墙在SP或PT直间那么就一定GG,看不到对方,因此我们可以狠狠地进行各种判断,暴力的分析模拟各种情况,以求得最终结果(不行不就随便rand或者输出嘛)

代码如下:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps=1e-8;
int sgn(double a)
{
    if (fabs(a)<eps) return 0;
    else
    {
        if (a>0.0) return 1;
        else return -1;
    }
}
struct point
{
    double x,y;
    point(){}
    point(double a,double b)
    {
        x=a;y=b;
    }
    void init()
    {
        scanf("%lf%lf",&x,&y);
    }
    point operator+(const point &a)const
    {
        point ans;
        ans.x=x+a.x;
        ans.y=y+a.y;
        return ans;
    }
    point operator-(const point &a)const
    {
        point ans;
        ans.x=x-a.x;
        ans.y=y-a.y;
        return ans;
    }
    point operator*(const double &a)const
    {
        point ans;
        ans.x=x*a;
        ans.y=y*a;
        return ans;
    }
    void print()
    {
        printf("%lf %lf\n",x,y);
    }
}v,p,w1,w2,m1,m2;
double cross(point a,point b){
    return a.x*b.y-a.y*b.x;
}
double dot(point a,point b){
    return a.x*b.x+a.y*b.y;
}
bool cross(point p1,point p2,point p3,point p4)
{
    if (sgn(cross(p2-p1,p3-p1))*sgn(cross(p2-p1,p4-p1))==1) return false;
    if (sgn(cross(p4-p3,p1-p3))*sgn(cross(p4-p3,p2-p3))==1) return false;
    if (sgn(max(p1.x,p2.x)-min(p3.x,p4.x))==-1) return false;
    if (sgn(max(p1.y,p2.y)-min(p3.y,p4.y))==-1) return false;
    if (sgn(max(p3.x,p4.x)-min(p1.x,p2.x))==-1) return false;
    if (sgn(max(p3.y,p4.y)-min(p1.y,p2.y))==-1) return false;
    return true;
}
point getcross(point p1,point p2,point p3,point p4)
{
    double a=p2.y-p1.y;
    double b=p1.x-p2.x;
    double c=-p1.x*p2.y+p1.y*p2.x;
    double d=p4.y-p3.y;
    double e=p3.x-p4.x;
    double f=-p3.x*p4.y+p3.y*p4.x;
    double x=(b*f-c*e)/(a*e-b*d);
    double y=(a*f-c*d)/(b*d-a*e);
    return point(x,y);
}
point calcfoot(point p1,point p2,point p3)
{
    double ratio=dot(p1-p2,p3-p2)/dot(p3-p2,p3-p2);
    return p2+(p3-p2)*ratio;
}
bool check()
{
    if (!cross(v,p,w1,w2))
    {
        if (!cross(v,p,m1,m2)) return true;
        if (sgn(cross(m1-v,m2-v))==0 && sgn(cross(m1-p,m2-p)==0)) return true;      
    }
    if (sgn(cross(m2-m1,v-m1))*sgn(cross(m2-m1,p-m1))==1)
    {
        point foot=calcfoot(p,m1,m2);
        foot=foot*2.0-p;
        if (cross(v,foot,m1,m2))
        {
            foot=getcross(v,foot,m1,m2);
            if (!cross(v,foot,w1,w2) && !cross(foot,p,w1,w2)) return true;
        }
    }
    return false;
}
int main()
{
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    v.init();
    p.init();
    w1.init();
    w2.init();
    m1.init();
    m2.init();
    if (check()) printf("YES\n");
    else printf("NO\n");
    return 0;
}

T3

【问题描述】
众所周知, 八数码问题是一个非常难的问题, 但把这道题简化一番。 现在给了你一个3 × 3的方格图, 你的目标是通过不断移动使得相邻颜色的块形成联通块。你每次的移动方式是选择一列或者一行进行置换滑动(这个解释起来比较麻烦, 看下面的图就懂了)。 所谓置换滑动, 就是所有格子沿着给定的方向顺次移动, 最后一个格子会被置换到最前面的过程。 现在给定整个方格图, 以及每个格子是否能够移动, 求使得相同颜色联通的最小步数。
【输入格式】
输入为3 × 3的方格图, 每个位置由五个字符组成, 前四个字符分别表示上下左右四个部分的颜色, 第五个字符表示该格子是否能够移动, 其中0是能移动1是不能移动。
【输出格式】
一行一个整数代表答案。
【样例输入】
GGGG0 GGGG0 GGGG0
OGOO0 GGGG0 OGOO0
OOOO0 OGGG1 OOOO0
【样例输出】
5
这里写图片描述

题解

暴力1:
真·暴力
什么判断都不加直接出样例——30
嗯,样例30

暴力2:
下面我们看看更加有深度的,额,暴力。。。。
炒鸡感谢zzy提供了第三题的解题情报

因为题目说明可以任意每行每列移动任意距离格子,那么对于每一个格子来说,它到任意一个地方在最优解下所耗费的步数不会超过2(步数<=2)
需要举个例子么?
例一:
这里写图片描述
右上角移到中间需要:下移一步,再左移一步
例二:
这里写图片描述
需要:下移一步然后右移(或者其他转移,最优情况下应该都是两步解决)

这样的话我们的最优化情况是多少次移动呢?
18次(因为每个格子都需要移动两步才能达到的话)
真的是18次么?
其实可以压缩到9次(每个格子移动时会替换掉另一个,当然,另一个也会去替换它或者别的格子,但是最终保持的都是每两个格子相对于原来的位置发生变换)
因此答案的范围大概就会限定在9步之内(这就是为什么puts(“5”);成功拿到30分的原因,太扎堆了)
真的是9次么?
它会给定不能移动的,而1步到位这样的数据估计不会给,而如果你八个格子全部移位到最优情况,那么剩下的那一个必定被迫最优化掉了,所以最坏情况是8种,如果出题人不很丧的话应该不会构造一个8的情况,因此我们的答案就在2~7中选择

因此如果我们搜索的话(emmmmmmm)每个格子的可能态有六种,
(2^6)^9
18014398509481984
嗯, 论述结束,下面开始扯正解吧emmm

正解?还没想出来啊w

先丢代码吧w

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>

using namespace std;

#define get(a,b,c) ((a-1)*12+(b-1)*4+c)

int en,tmp[4][4],color[37],map[9][5],q[37],nowmap[4][4],newmap[4][4];

bool num[9],use[90000000],right[37],row[4],col[4],col_find[5];

char s[10];

struct rec
{
    int sta,step;
    rec(){}
    rec(int a,int b)
    {
        sta=a;step=b;
    }
};

queue<rec> que;

struct edge
{
    int e;
    edge *next;
}*v[37],ed[100];

void add_edge(int s,int e)
{
    en++;
    ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;
    en++;
    ed[en].next=v[e];v[e]=ed+en;v[e]->e=s;
}

bool check(int nows)
{
    memset(num,false,sizeof(num));
    for (int a=3;a>=1;a--)
        for (int b=3;b>=1;b--)
            if (a!=3 || b!=3)
            {
                tmp[a][b]=nows%10;
                num[nows%10]=true;
                nows/=10;
            }
    for (int a=0;a<9;a++)
        if (!num[a])
        {
            tmp[3][3]=a;
            break;
        }
    int cnt=0;
    for (int a=1;a<=3;a++)
        for (int b=1;b<=3;b++)
            for (int c=1;c<=4;c++)
            {
                cnt++;
                color[cnt]=map[tmp[a][b]][c];
            }
    memset(right,false,sizeof(right));
    memset(col_find,false,sizeof(col_find));
    for (int a=1;a<=36;a++)
        if (!right[a])
        {
            if (col_find[color[a]]) return false;
            col_find[color[a]]=true;
            int front=1,tail=1;
            q[1]=a;
            right[a]=true;
            for (;front<=tail;)
            {
                int now=q[front++];
                for (edge *e=v[now];e;e=e->next)
                    if (color[e->e]==color[now] && !right[e->e])
                    {
                        right[e->e]=true;
                        q[++tail]=e->e;
                    }
            }
        }
    return true;
}

int main()
{
    freopen("c.in","r",stdin);
    freopen("c.out","w",stdout);

    for (int a=1;a<=3;a++)
        for (int b=1;b<=3;b++)
        {
            add_edge(get(a,b,1),get(a,b,3));
            add_edge(get(a,b,1),get(a,b,4));
            add_edge(get(a,b,2),get(a,b,3));
            add_edge(get(a,b,2),get(a,b,4));
            if (a!=3) add_edge(get(a,b,2),get(a+1,b,1));
            if (b!=3) add_edge(get(a,b,4),get(a,b+1,3));
        }
    int cnt=0;
    for (int a=1;a<=3;a++)
        for (int b=1;b<=3;b++)
        {
            scanf("%s",s+1);
            for (int c=1;c<=4;c++)
                if (s[c]=='R') map[cnt][c]=0;
                else 
                {
                    if (s[c]=='G') map[cnt][c]=1;
                    else
                    {
                        if (s[c]=='B') map[cnt][c]=2;
                        else map[cnt][c]=3;
                    }
                }
            if (s[5]=='1') row[a]=col[b]=true;
            cnt++;
        }
    int nows=1234567;
    if (check(nows))
    {
        printf("0\n");
        return 0;
    }
    que.push(rec(nows,0));
    use[nows]=true;
    rec now;
    while (que.size())
    {
        now=que.front();
        que.pop();
        int step=now.step;
        int nows=now.sta;
        memset(num,false,sizeof(num));
        for (int a=3;a>=1;a--)
            for (int b=3;b>=1;b--)
                if (a!=3 || b!=3)
                {
                    nowmap[a][b]=nows%10;
                    num[nows%10]=true;
                    nows/=10;
                }
        for (int a=0;a<9;a++)
            if (!num[a])
            {
                nowmap[3][3]=a;
                break;
            }
        int news=0;
        for (int a=1;a<=3;a++)
        {
            if (!row[a])
            {
                for (int b=1;b<=3;b++)
                    for (int c=1;c<=3;c++)
                        newmap[b][c]=nowmap[b][c];
                int x=newmap[a][1];
                newmap[a][1]=newmap[a][2];newmap[a][2]=newmap[a][3];newmap[a][3]=x;
                news=0;
                for (int b=1;b<=3;b++)
                    for (int c=1;c<=3;c++)
                        if (b!=3 || c!=3) news=news*10+newmap[b][c];
                if (!use[news])
                {
                    use[news]=true;
                    if (check(news))
                    {
                        printf("%d\n",step+1);
                        return 0;
                    }
                    que.push(rec(news,step+1));
                }
                x=newmap[a][1];
                newmap[a][1]=newmap[a][2];newmap[a][2]=newmap[a][3];newmap[a][3]=x;
                news=0;
                for (int b=1;b<=3;b++)
                    for (int c=1;c<=3;c++)
                        if (b!=3 || c!=3) news=news*10+newmap[b][c];
                if (!use[news])
                {
                    use[news]=true;
                    if (check(news))
                    {
                        printf("%d\n",step+1);
                        return 0;
                    }
                    que.push(rec(news,step+1));
                }
            }
            if (!col[a])
            {
                for (int b=1;b<=3;b++)
                    for (int c=1;c<=3;c++)
                        newmap[b][c]=nowmap[b][c];
                int x=newmap[1][a];
                newmap[1][a]=newmap[2][a];newmap[2][a]=newmap[3][a];newmap[3][a]=x;
                news=0;
                for (int b=1;b<=3;b++)
                    for (int c=1;c<=3;c++)
                        if (b!=3 || c!=3) news=news*10+newmap[b][c];
                if (!use[news])
                {
                    use[news]=true;
                    if (check(news))
                    {
                        printf("%d\n",step+1);
                        return 0;
                    }
                    que.push(rec(news,step+1));
                }
                x=newmap[1][a];
                newmap[1][a]=newmap[2][a];newmap[2][a]=newmap[3][a];newmap[3][a]=x;
                news=0;
                for (int b=1;b<=3;b++)
                    for (int c=1;c<=3;c++)
                        if (b!=3 || c!=3) news=news*10+newmap[b][c];
                if (!use[news])
                {
                    use[news]=true;
                    if (check(news))
                    {
                        printf("%d\n",step+1);
                        return 0;
                    }
                    que.push(rec(news,step+1));
                }
            }
        }
    }

    return 0;
}
项目计划书:BRCM Wi-Fi 功率与速率控制模块开发与验证 起始日期:2024年9月15日 截止日期:2024年10月31日 一、项目目标 本项目旨在深入理解并实现 BRCM Wi-Fi 芯片方案中的以下核心模块: 802.11 基本速率集 认证功率表(Regulatory Power Table)的结构与实现原理 DFS 规则与 Sub Channel 的处理逻辑 Board Limit Power 的配置与生效机制 Target Power 的计算算法与代码实现 基于 Excel 的功率表自动生成工具(C语言实现) 功率测试拓扑与验证 目标机型:BE900v2 开发语言:C 语言 + Python 二、详细计划(甘特图形式) 时间段 任务 交付物 9.15 - 9.21 阶段1:知识梳理与文档总结 • 梳理802.11基本速率集 • 梳理Regulatory Power表结构与DFS规则 • 梳理Board Limit Power参数含义 • 梳理Target Power计算逻辑 《BRCM Wi-Fi 功率与速率控制原理总结文档》 9.22 - 9.28 阶段2:目标功率算法实现 • 实现calculate_target_power()函数 • 包括Board Limit、Regulatory Power、DFS、温度补偿等模块 • 编写测试用例验证算法 《目标功率算法实现代码》 《测试结果输出示例》 9.29 - 10.5 阶段3:认证功率表生成工具设计 • 设计Excel格式模板 • 开发C语言工具解析Excel/CSV • 生成C语言结构体数组 • 支持新旧驱动兼容性 《认证功率表生成工具源码》 《Excel 示例模板》 《工具使用说明》 10.6 - 10.12 阶段4:认证功率表工具开发 • 完成工具编码 • 支持DFS标记与Sub Channel处理 • 支持多国家码、信道、带宽配置 《认证功率表生成工具可执行文件》 《生成的C结构体代码》 10.13 - 10.19 阶段5:功率测试环境搭建与验证 • 搭建测试拓扑 • 编写Python测试脚本 • 验证基本速率集、功率限制、DFS检测等 《测试拓扑图》 《测试脚本与输出日志》 10.20 - 10.26 阶段6:功率测试执行与结果分析 • 执行多组测试 • 验证Regulatory Power、Board Limit、DFS切换等 • 分析测试结果与预期是否一致 《功率测试报告》 10.27 - 10.31 阶段7:文档整理与最终交付 • 整理所有文档 • 汇总代码、测试结果、工具说明 • 输出最终交付物 《BRCM Wi-Fi 功率与速率控制原理与实现》 《目标功率算法实现代码》 《认证功率表生成工具》 《测试拓扑与结果报告》 三、关键节点 时间 关键节点 9.21 完成理论知识梳理 9.28 完成目标功率算法实现 10.5 完成认证功率表生成工具设计 10.12 完成工具开发与测试 10.19 完成功率测试环境搭建 10.26 完成功率测试执行 10.31 最终交付 四、人员分工建议 角色 职责 技术负责人 技术架构设计、关键算法实现 C语言开发 功率表生成工具开发 Python开发 测试脚本编写 测试工程师 搭建测试环境、执行验证 文档工程师 编写技术文档与说明 五、工具与环境准备 工具 说明 GCC / Clang C语言编译器 Python 3.x 测试脚本 Excel / CSV 功率表输入格式 NVRAM 工具 nvram, wl, iw Wi-Fi 测试仪 用于功率验证 Git 版本管理 六、风险与应对 风险 应对措施 Excel解析困难 支持CSV替代 新旧驱动兼容性问题 使用宏定义兼容 功率测试环境搭建困难 使用虚拟机+模拟器替代 算法理解偏差 多轮代码Review与文档确认 七、最终交付物清单 《BRCM Wi-Fi 功率与速率控制原理与实现》 《目标功率算法实现代码》 《认证功率表生成工具源码与可执行文件》 《Excel 示例模板》 《测试拓扑与结果报告》 —很好,但是我要提醒一下,我是要根据硬件excel认证功率表自动生成excel功率表,不是生成可用于驱动的 C 语言格式的功率表代码
09-13
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值