2022/5/30

觉得还是得每周记录一下刷过的题,分析题目和做题思路,对近期学习阶段总结一下。

记录原则,当时存在的问题,和题目正确的思路

目录

简单搜索签到

抽卡

挖隧道安全版

Baimuii的双向队列

Funny哥卖锅盔

阿毛与王爷

一个人挺好

啵啵小狗自动机(easy version)

南湖的瓜

雨声里的相遇

花海

啵啵小狗自动机(hard version)

南湖的瓜-续



南华校赛:

简单搜索签到

马走日直接八个方向遍历就出来了,因为题目要求点在1,1以上,边界没有continue好,在垃圾编译环境下debug半天,而且贡献了一发ce 555,所以不仅要会板子,还得根据题目实事求是。

抽卡

规律题,队友打表写的,多列出几项发现就是2的n次方

挖隧道安全版

思路如上,dp在于状态选择,状态划分,最后状态转移

void solved()
{
d[1][0]=a[1];//前1次,当前不炸的最大价值
	d[1][1]=60;//前1次,当前炸的最大价值
	for(int i=2;i<=n;i++){
		d[i][0]=min(d[i-1][0],d[i-1][1])+a[i];
		d[i][1]=min(d[i-1][0]+60,d[i][1]);//直接min不用分类讨论
		if(i>=3)//第1次转移到第三次
			d[i][1]=min(d[i-3][0]+150,d[i][1]);
}

Baimuii的双向队列

问题最难处理是怎么每次只操作一小段并且送回去,一开始跟队友一起模拟字符串改位置,debug烂了,没时间也没那么多精力

正解:利用string容器,要处理区间长度,写cin>>str,str=" "+str;方便处理区间

substr提取k%len(修改区间的长度)实现优化,再用replace将修改后的字符串送回去

int main() {
cin >> str >> m;
str = " " + str;
while (m--) {
string op;
long long l, r, k;
cin >> op;
if (op == "R") {
cin >> l >> r >> k;
int len = r - l + 1;
k %= len;
if (k == 0)
continue;
string s1, s2;
s1 = str.substr(l + len - k, k), s2 = str.substr(l, len - k);
str.replace(l, k, s1), str.replace(l + k, len - k, s2);
} else if (op == "L") {
cin >> l >> r >> k;
int len = r - l + 1;
k %= len;
if (k == 0)
continue;
string s1, s2;
s1 = str.substr(l, k), s2 = str.substr(l + k, len - k);
str.replace(l + len - k, k, s1), str.replace(l, len - k, s2);
} else {
for (int i = 1; i < str.size(); i++) {
cout << str[i];
}
puts("");
}
}
return 0;
}

第四届SCPC中南民族大学

Funny哥卖锅盔

栈模拟吧,没看到数据保证m小于n,即不会出现需要重新遍历原串的情况,不知道自己写的模拟循环在哪里超时了。。。

正解:while(1)和if continue顺序是没问题的,自己模拟只过了86%的数据,这种时候就要加代码强行排除情况,比如在出栈操作后,加i指针越界break,判断栈的状态

void solved()
{
    cin>>n>>m>>s1>>s2;
     stack<char> st;
    if(strlen(s1)==strlen(s2))
    {
        len=strlen(s2);
        while(1)
        {
            if(!st.empty()&&st.top()==s2[j])
            { st.pop(),j++;continue;}
            
            if(i>=len)break;
            
            if(s2[j]==s1[i])
            {i++,j++;continue;}
            
            if(st.size()<m)
            {st.push(s1[i]),i++;continue;}
            
            printf("That's not Funny at all!\n");
            return;
        }
    }
    else{
        printf("That's not Funny at all!\n");return;
    }
    if(st.empty())printf("Don't you think that's Funny?\n");
    else {
        printf("That's not Funny at all!\n");
    }
    ;
}

阿毛与王爷

异或题,发现很多异或都是找二进制规律,自己独立写的时候没考虑到1多的情况,以为直接0。

正解:保证1的个数必须为n,那么很简单考虑大于1改0算二进制,等于为0,小于0改1算二进制,保证数据小于X

void solved()
{
    int n,x;cin>>n>>x;
    int a=0,b=0;
     
    for(int i=0;i<31;i++)
        if(x>>i&1)a++;
    else b++;
     
    int y=0;
    if(a==n)printf("Piaoliangdehenna!\n%d\n",0);
    else if(a<n)
    {
        int res=0;
        int cnt=n-a;
        //cout<<a<<endl;
        //cout<<cnt<<endl;
        for(int i=0;i<31&&cnt;i++)
        if(x>>i&1);
        else res+=pow(2,i),cnt--;
         
        if(res<=x)printf("Piaoliangdehenna!\n%d\n",res);
        else puts("Chuola!");
    }
    else{
        int res=0;
        for(int i=0;i<31&&a!=n;i++)
            if(x>>i&1)res+=1<<i,a--;
        if(res<=x)printf("Piaoliangdehenna!\n%d\n",res);
        else puts("Chuola!");
    }
     
    ;
}

一个人挺好

构造类题目,只要保证符合题意构造,不需要和样例一模一样,一般就是思维找规律

正解:剩余101010如此,该串后面补多出来对数>>1的0即可

void solved()
{
    int n,m;cin>>n>>m;
     
    if((m-n)%2==1)puts("-1");
    else {
        int cnt=m-n;
        for(int i=1;i<=n;i++)
            cout<<(i%2==1)?1:0;
        while(cnt--)
            cout<<0;
        puts("");
    }
     
    ;
}

啵啵小狗自动机(easy version)

打表题,sb了,手打表验证没问题,打数据确实有点牛马,尽量代码实现吧

正解:找到较大的个数下(i+1方-i方大于100)i>99/2都可以,把答案标记一下就可以了

bool st[1000];
int main()
{
    for(int i=1;i<=50;i++)
        for(int j=i+1;j<=50;j++)
            if(j*j-i*i<=100)st[j*j-i*i]=1;
    int n;cin>>n;
    puts(st[n]?"YES":"NO");
}

南湖的瓜

队友写的,看了下题感觉就是floodfill统计连通块取个数最大的俩个连通块

正解:就是这个思路

发现问题,还是根据题目意思,一般尽量用st判断来bfs,因为不能走同样的路

char g[N][N];
int n, m;
 
int dx[] = { 0,1,0,-1 }, dy[] = { 1,0,-1,0 };
 
bool st[N][N];
 
bool cmp(int x,int y)
{
    return x>y;
}
int bfs(int x, int y)
{
    int cnt = 1;
    queue<PII> q;
    q.push({ x,y });
    st[x][y]=1;
    g[x][y]='.';
 
    while (q.size())
    {
        auto t = q.front(); q.pop();
        for (int i = 0; i < 4; i++)
        {
            int xx = t.first + dx[i], yy = t.second + dy[i];
            
            if (xx < 0 || xx >= n || yy < 0 || yy >= m || g[xx][yy] == '#'||st[xx][yy])continue;
            if(g[xx][yy]=='*')cnt++;
            q.push({ xx,yy });
            g[xx][yy]='.';
            st[xx][yy]=1;
            // printf("%d %d %d\n",xx,yy,cnt);
        }
    }
 
    return cnt;
}
void solved()
{
    cin >> n >> m;
 
    for (int i = 0; i < n; i++)cin >> g[i];
 
    vector<int> res;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
            if (g[i][j] == '*')
                res.pb(bfs(i, j));
    }
 
  // for(auto x:res)cout<<x<<endl;
    sort(res.begin(), res.end(),cmp);
    if(res.size()==1)cout<<res[0]<<"\n";
    else
    printf("%d\n", res[0] + res[1]);
}

雨声里的相遇

自己写的时候奇数偶数长度的性质判断没处理好,没有过全部数据

正解:十进制转n进制,回文字符串,前一半必须严格上升,

判断顺序回文中,注意偶数要多--,奇数取原长度比2就行了

char mp[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G',
           'H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X',
           'Y','Z'};
 
bool check(string s)
{
    for(int i=0,j=s.size()-1;i<s.size()/2;i++,j--)
        if(s[i]!=s[j])return false;
    return true;
}
void solved()
{
    int n,s;cin>>n>>s;
     
   /* for(int i=0;i<36;i++)
    {
        if(i<10)printf("'%d',",i);
        else if(i<36)
            printf("'%c',",i-10+'A');
    }*/
    ;
 
    bool ok=0;
    for(int i=2;i<=n;i++)
    {
        int tmp=s;
        string res;
        while(tmp)
        {
            res+=mp[tmp%i];
            tmp/=i;
        }
        bool flag=1;
         
                if(check(res))
                {
                    int len=res.size()/2;
                    if(res.size()%2==0)len--;
                     
                for(int i=0;i<len;i++)
                {
                    if(res[i]>=res[i+1]){flag=0;break;}
                }
                     
                if(flag)
                {
                    ok=1;
                  printf("%d ",i);
                    cout<<res<<"\n";
                }
             }
        }
    if(!ok)puts("guomienasai");
}

花海

自己有思路,很难实现

正解:向量叉乘,给出o点,求每个三角如oab,求和矢量性质,包括首尾,

Soab==x1*y2-x2*y1

struct node
{
    int x,y;
}q[N];
void solved()
{
    int n;cin>>n;
     
    for(int i=0;i<n;i++)
        cin>>q[i].x>>q[i].y;
    q[n].x=q[0].x,q[n].y=q[0].y;
    double res=0;
     
    for(int i=0;i<n;i++)
    {
        res+=q[i].x*q[i+1].y-q[i].y*q[i+1].x;
    }
    res/=2;
    printf("%.3lf\n",fabs(res));
    ;
}

啵啵小狗自动机(hard version)

数据量变大,不再可以模拟打记录,观察打出来的多组数据,发现(i+1)^2-i^2一定是奇数或者被4整除

南湖的瓜-续

输出一组符合题意得案例,直接特殊值0就能过

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值