SSL Week 3 总结&解题报告

110 篇文章 1 订阅
107 篇文章 1 订阅

总结

日期事件刷的题
Day 0 星期日做文档,写作业,刷比赛购物券(dfs+hash)
Day 1 星期一完善了博客
Day 2 星期二讲课NOI元旦
Day 3 星期三做题格子游戏
Day 4 星期四刷题,写博客矩形,搭配购买,旅行,嫌疑犯宗教,雀斑
Day 5 星期五出题
Day 6 星期六模拟赛模拟赛的题

时间复杂度

题目时间复杂度
第一题 奇数 O(tofrom2) O ( t o − f r o m 2 )
第二题 求和 O(n+nn) O ( n + n n )
第三题 圆环 O(n+i=11..nlog(ai)) O ( n + ∑ 1.. n i = 1 l o g ( a i ) )
第四题 翻转 O(4n2) O ( 4 n 2 )
第五题 得分 O(nlogn+nm) O ( n l o g n + n m )
第六题 重要人物 O(n2+2G+KE) O ( n 2 + 2 G + K E )

解题报告

废话不多说,直接放题目
第一题
第二题
第三题
第四题
第五题
第六题
第七题
第八题

第一题 奇数

思路

最水的题,直接暴力。顺便练习下骚库(STL)

代码

#include<cstdio>
#include<vector>
using namespace std;int from,to;
vector<int>odd;
int main()
{
    scanf("%d%d",&from,&to);//输入
    if(!(from&1)) from++;if(!(to&1)) to--;//一些小优化
    for(int i=from;i<=to;i+=2) odd.push_back(i);//放入
    printf("%d\n",odd.size());//输出数量
    for(int i=0;i<odd.size();i++)
     printf("%d\n",odd[i]);//输出
}

第二题 求和

思路

直接模拟

代码

#include<cstdio>
#define r(i,a,b) for(int i=a;i<=b;i++)
using namespace std;int s,n=1,k,ans[101],p;
bool h[100001];
bool check(int x)//暴力判断
{
    if(!x) return true;//正好相等
    if(x&1) return false;//不是偶数
    x>>=1;//变成一半
    if(h[x]) //是否存在
    {
        ans[++p]=x;
        return true;//存在输出
    }
    r(i,1,n-1)
     r(j,i+1,n)
      if(i+j==x)//存在
       {
        ans[++p]=i;
        ans[++p]=j;
        return true;//继续查找
       }
    return false;//不存在
}
int main()
{
    scanf("%d",&s);
    while(k+n<s)
     k+=n,h[n++]=1;
    k+=n;//暴力高斯定理
    do
    {
        if(check(k-s))//暴力判断
         {
            printf("%d\n",n);//输出
            r(i,1,p) printf("%d\n",ans[i]);//暴力输出
            return 0;
         }
        k+=++n;h[n]=1;//继续找
    }while(1);//暴力搜
}

第三题 圆环

思路

一波暴力的辗转相除法,尽管我是用了骚库(STL)

代码

#include<cstdio>
#include<algorithm>
using namespace std;int n,a,b;
int main()
{
    scanf("%d\n%d",&n,&a);//输入
    while(--n)//循环
     scanf("%d",&b),printf("%d/%d\n",a/__gcd(a,b),b/__gcd(a,b));//输出
}

第四题 翻转

思路

暴力模拟
翻转三次,每次对应的格子位置为

x[j][ni+1] x [ j ] [ n − i + 1 ]

x[ni+1][nj+1] x [ n − i + 1 ] [ n − j + 1 ]

x[nj+1][i] x [ n − j + 1 ] [ i ]

当然,也可以直接三次这样子。
x[k1][j][ni+1] x [ k − 1 ] [ j ] [ n − i + 1 ]

代码

#include<cstdio>
#define r(i,a,b) for(int i=a;i<=b;i++)
using namespace std;int n,ans;char c;
bool x[4][501][501];
int make(int k,int i,int j)
{
    if(k==1) return x[0][j][n-i+1];
    if(k==2) return x[0][n-i+1][n-j+1];
    if(k==3) return x[0][n-j+1][i];//一波暴力
}
int main()
{
    scanf("%d",&n);
    r(i,1,n)
    {
        c=getchar();
        r(j,1,n)
        {
            c=getchar();x[0][i][j]=c=='1';ans+=x[0][i][j];
        }//输入不解释
    }
    printf("%d\n",ans);
    r(k,1,3)//翻转三个
    {
        r(i,1,n)
         r(j,1,n)
            if(make(k,i,j)>x[k-1][i][j])
             x[k][i][j]=make(k,i,j),ans++;//如果能够覆盖
            else
             x[k][i][j]=x[k-1][i][j];//否则
        printf("%d\n",ans);//输出
    }
}

第五题 得分

思路

20分思路,dfs
30分思路,贪心
100分思路,动态规划+贪心
动态转移方程

f[j]=max{f[jt[i]+c[i](mj+t[i])} f [ j ] = m a x { f [ j − t [ i ] + c [ i ] ∗ ( m − j + t [ i ] ) }

贪心时间复杂度: O(nlogn+n) O ( n l o g n + n )
贪心空间复杂度: O(2n) O ( 2 n )
动规时间复杂度: O(nlogn+nm) O ( n l o g n + n m )
动规时间复杂度: O(3n) O ( 3 n )

贪心代码

#include<cstdio>
#include<algorithm>
#define r(i,a,b) for(int i=a;i<=b;i++)
using namespace std;int n,m,ans;
struct node
{
    int t,c;
}p[3001];
bool cmp(node x,node y){return x.t/1.0/x.c<y.t/1.0/y.c;}//按比例排序
int main()
{
    scanf("%d%d",&n,&m);
    r(i,1,n) scanf("%d%d",&p[i].t,&p[i].c);
    stable_sort(p+1,p+1+n,cmp);
    for(int i=1;i<=n;i++)
     if(m>=p[i].t)//一波贪心
      {
        ans+=m*p[i].c;
        m-=p[i].t;
      }
    printf("%d",ans);//输出
}

动态规划代码

#include<cstdio>
#include<algorithm>
#define r(i,a,b) for(int i=a;i<=b;i++)
using namespace std;int n,m,ans,f[10001],tot;
struct node
{
    int t,c;
}p[3001];
bool cmp(node x,node y){return x.t/1.0/x.c<y.t/1.0/y.c;}
void dp()//动态规划
{
    r(i,1,n)
     for(int j=m;j>=p[i].t;j--)
      if(f[j-p[i].t]+p[i].c*(m-j+p[i].t)>f[j])
       f[j]=f[j-p[i].t]+p[i].c*(m-j+p[i].t);
    r(i,1,m)
     tot=max(f[i],tot);
}
int main()
{
    scanf("%d%d",&n,&m);
    r(i,1,n) scanf("%d%d",&p[i].t,&p[i].c);
    stable_sort(p+1,p+1+n,cmp);//排序这里用了贪心的思想
    dp();
    printf("%d",tot);//输出
}

第六题 重要人物

思路

Spfa+预处理
对于大人物走的路,可以一波预处理,把这些路用一个数组来表示。 lazyi,j.begin l a z y i , j . b e g i n 表示第i个点到第j个点大人物进入的起始时间。 lazyi,j.end l a z y i , j . e n d 表示第i个点到第j个点大人物出去的时间。
然后只需要在spfa里面加上这样一个语句
if(dis[u]>=lazy[u][v].begin i f ( d i s [ u ] >= l a z y [ u ] [ v ] . b e g i n && dis[u]<lazy[u][v].end) d i s [ u ] < l a z y [ u ] [ v ] . e n d )
表示如果这条路大人物会经过的话则

w+=lazy[u][v].enddis[u] w + = l a z y [ u ] [ v ] . e n d − d i s [ u ]

等待大人物

代码

#include<cstdio>
#include<queue>
#include<vector>/*其实这题用邻接表会更好,但为了练习STL库,还是用了vecotr和queue*/
#include<algorithm>
#define r(i,a,b) for(int i=a;i<=b;i++)
using namespace std;int n,m,A,B,K,G,x,y,w,l[1001][1001],dis[1001],p[1001];//p表示大人物经过的城市
struct node
{
    int begin,end;
}lazy[1001][1001];//一波结构体
vector<int>g[1001];//一波骚库
void spfa()//一波spfa
{
    int from=A;
    queue<int>q;q.push(from);//日常骚库
    bool vis[1001]={0};vis[from]=true;
    dis[from]=K;//这里初始为K,到最后再减
    while(!q.empty())
    {
        int u=q.front();q.pop();vis[u]=true;
        r(i,0,g[u].size()-1)
         {
            int w=l[u][g[u][i]],v=g[u][i];
            if(dis[u]>=lazy[u][v].begin&&dis[u]<lazy[u][v].end) w+=lazy[u][v].end-dis[u];//骚操作
            if(dis[u]+w<dis[v])
             {
                dis[v]=dis[u]+w;
                if(!vis[v])
                 q.push(v),vis[v]=true;//一波spfa
             }
         }
        vis[u]=false;
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    scanf("%d%d%d%d",&A,&B,&K,&G);//输入
    r(i,0,n-1)
     r(j,i+1,n)
      dis[i]=dis[j]=l[i][j]=l[j][i]=536870912;
    r(i,1,G) scanf("%d",&p[i]);//输入
    r(i,1,m)
    {
        scanf("%d%d%d",&x,&y,&w);
        g[x].push_back(y);
        g[y].push_back(x);
        l[x][y]=l[y][x]=w;//日常spfa
    }
    lazy[p[2]][p[1]].begin=lazy[p[1]][p[2]].begin=0;
    lazy[p[2]][p[1]].end=lazy[p[1]][p[2]].end=l[p[1]][p[2]];
    lazy[p[3]][p[2]].begin=lazy[p[2]][p[3]].begin=lazy[p[1]][p[2]].end;
    lazy[p[3]][p[2]].end=lazy[p[2]][p[3]].end=lazy[p[1]][p[2]].end+l[p[2]][p[3]];
    r(i,4,G)
    {
        lazy[p[i-1]][p[i]].begin=lazy[p[i]][p[i-1]].begin=lazy[p[i-1]][p[i-2]].end;
        lazy[p[i-1]][p[i]].end=lazy[p[i]][p[i-1]].end=lazy[p[i-1]][p[i]].begin+l[p[i-1]][p[i]];
    }//一波lazy操作,只可意会不可言传。
    spfa();//spfa
    printf("%d",dis[B]-K);//输出
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可 6私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值