第四次CCF计算机软件能力认证

AcWing 3212. 图像旋转

旋转是图像处理的基本操作,在这个问题中,你需要将一个图像逆时针旋转 90 度。

计算机中的图像表示可以用一个矩阵来表示,为了旋转一个图像,只需要将对应的矩阵旋转即可。

输入格式

输入的第一行包含两个整数 n,m,分别表示图像矩阵的行数和列数。

接下来 n 行每行包含 m 个整数,表示输入的图像。

输出格式

输出 m 行,每行包含 n 个整数,表示原始矩阵逆时针旋转 90 度后的矩阵。

数据范围

1≤n,m≤1,000
矩阵中的数都是不超过 1000 的非负整数。

输入样例

2 3
1 5 3
3 2 4

输出样例

3 4
5 2
1 3

 画完图之后直接暴力枚举即可 AC:

#include<iostream>
using namespace std;
const int N=1e3+5;
int n,m,a[N][N];
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>a[i][j];
    for(int j=m;j>=1;j--){
        for(int i=1;i<=n;i++){
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

AcWing 3213. 数字排序

给定 n 个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出。

输入格式

输入的第一行包含一个整数 n,表示给定整数的个数。

第二行包含 n 个整数,相邻的整数之间用一个空格分隔,表示所给定的整数。

输出格式

输出多行,每行包含两个整数,分别表示一个给定的整数和它出现的次数。

按出现次数递减的顺序输出。如果两个整数出现的次数一样多,则先输出值较小的,然后输出值较大的。

数据范围

1≤n≤1000
给出的数都是不超过 1000 的非负整数。

输入样例

12
5 2 3 3 1 3 4 2 5 2 3 5

输出样例

3 4
2 3
5 3
1 1
4 1

map(去重并且计数)+vector(存答案方便排序操作)+sort(按照次数升序排序) AC:

#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
int n;
map<int,int>num;
vector<pair<int,int>>ans;
bool cmp(pair<int,int>x,pair<int,int>y){
    if(x.second==y.second) return x.first<y.first;
    return x.second>y.second;
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        int t;
        cin>>t;
        num[t]++;
    }
    for(auto x:num) ans.push_back(x);
    sort(ans.begin(),ans.end(),cmp);
    for(auto x:ans) cout<<x.first<<" "<<x.second<<endl;
    return 0;
}

AcWing 3214. 节日

有一类节日的日期并不是固定的,而是以“a 月的第 b 个星期 c”的形式定下来的,比如说母亲节就定为每年的五月的第二个星期日。

现在,给你 a,b,c 和 y1,y2,希望你输出从公元 y1 年到公元 y2 年间的每年的 a 月的第 b 个星期 c 的日期。

提示:关于闰年的规则:年份是 400 的整数倍时是闰年,否则年份是 4 的倍数并且不是 100 的倍数时是闰年,其他年份都不是闰年。

例如 1900 年就不是闰年,而 2000 年是闰年。

为了方便你推算,已知 1850 年 1 月 1 日是星期二。

输入格式

输入包含恰好一行,有五个整数 a,b,c,y1,y2。

其中 c=1,2,……,6,7 分别表示星期一、二、……、六、日。

输出格式

对于 y1 和 y2 之间的每一个年份,包括 y1 和 y2,按照年份从小到大的顺序输出一行。

如果该年的 a 月第 b 个星期 c 确实存在,则以 yyyy/mm/dd 的格式输出,即输出四位数的年份,两位数的月份,两位数的日期,中间用斜杠 / 分隔,位数不足时前补零。

如果该年的 a 月第 b 个星期 c 并不存在,则输出 none

数据范围

1≤a≤12
1≤b≤5
1≤c≤7
1850≤y1,y2≤2050

输入样例

5 2 7 2014 2015

输出样例

2014/05/11
2015/05/10

日期问题 模拟AC:

#include<iostream>
using namespace std;
int a,b,c,y1,y2,flag[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool isLeapYear(int y){
    return ((y%400==0)||(y%4==0&&y%100!=0));
}
int weekSince1850(int year,int month,int day) {
    int week=1;
    for(int y=1850;y<year;y++){
        week+=365+isLeapYear(y);
        week%=7;
    }
    for(int m=1;m<month;m++) {
        week+=flag[m]+(m==2&&isLeapYear(year));
        week%=7;
    }
    week+=day;
    week%=7;
    return week;
}
int main(){
    cin>>a>>b>>c>>y1>>y2;
    c%=7;
    for(int y=y1;y<=y2;y++){
        bool key=false;
        int m=a;
        bool leap=(m==2&&isLeapYear(y));
        int cnt=0;
        for(int d=1;d<=flag[m]+leap;d++){
            if(weekSince1850(y,m,d)==c) cnt++;
            if(cnt==b) {printf("%d/%02d/%02d\n",y,m,d); key=true; break;}
        }
        if(!key) cout<<"none"<<endl;
    }
    return 0;
}

AcWing 3215. 网络延时

给定一个公司的网络,由 n 台交换机和 m 台终端电脑组成,交换机与交换机、交换机与电脑之间使用网络连接。

交换机按层级设置,编号为 1 的交换机为根交换机,层级为 1。

其他的交换机都连接到一台比自己上一层的交换机上,其层级为对应交换机的层级加 1。

所有的终端电脑都直接连接到交换机上。

当信息在电脑、交换机之间传递时,每一步只能通过自己传递到自己所连接的另一台电脑或交换机。

请问,电脑与电脑之间传递消息、或者电脑与交换机之间传递消息、或者交换机与交换机之间传递消息最多需要多少步。

输入格式

输入的第一行包含两个整数 n,m,分别表示交换机的台数和终端电脑的台数。

第二行包含 n−1 个整数,分别表示第 2、3、……、n 台交换机所连接的比自己上一层的交换机的编号。第 i 台交换机所连接的上一层的交换机编号一定比自己的编号小。

第三行包含 m 个整数,分别表示第 1、2、……、m 台终端电脑所连接的交换机的编号。

输出格式

输出一个整数,表示消息传递最多需要的步数。

数据范围

前 30% 的评测用例满足:n≤5,m≤5
前 50% 的评测用例满足:n≤20,m≤20
前 70% 的评测用例满足:n≤100,m≤100
所有评测用例都满足:1≤n≤10000,1≤m≤10000

输入样例1

4 2
1 1 3
2 1

输出样例1

4

样例1解释

样例的网络连接模式如下,其中圆圈表示交换机,方框表示电脑:

network1.png

其中电脑 1 与交换机 4 之间的消息传递花费的时间最长,为 4 个单位时间。

输入样例2

4 4
1 2 2
3 4 4 4

输出样例2

4

样例2解释

样例的网络连接模式如下:

network2.png

其中电脑 1 与电脑 4 之间的消息传递花费的时间最长,为 4 个单位时间。

在做这题前先复习道关于 树的直径 模板题:

核心思路是:以任意点出发,找到距离该点最远的2条路径,加起来就是直径

AcWing 1072. 树的最长路径

给定一棵树,树中包含 n 个结点(编号1~n)和 n−1 条无向边,每条边都有一个权值。

现在请你找到树中的一条最长路径。

换句话说,要找到一条路径,使得使得路径两端的点的距离最远。

注意:路径中可以只包含一个点。

输入格式

第一行包含整数 n。

接下来 n−1 行,每行包含三个整数 ai,bi,ci,表示点 ai 和 bi 之间存在一条权值为 ci 的边。

输出格式

输出一个整数,表示树的最长路径的长度。

数据范围

1≤n≤10000
1≤ai,bi≤n
−10^5≤ci≤10^5

输入样例

6
5 1 6
1 4 5
6 3 9
2 6 8
6 1 7

输出样例

22

树的最长路径 AC: 

#include<iostream>
#include<vector>
using namespace std;
const int N=1e4+5;
int n,ans;
vector<pair<int,int>>G[N];
int dfs(int u,int father){
    int d1=0,d2=0;   //分别用于存储当前节点的最长和次长路径长度
    for(auto t:G[u]){
        int point=t.first,val=t.second;
        if(point==father) continue;//避免回到父节点
        int d=dfs(point,u)+val;    //计算从邻接节点出发的最长路径长度,并加上边权
        //更新最长和次长路径长度
        if(d>=d1) d2=d1,d1=d;
        else if(d>d2) d2=d;
    }
    ans=max(ans,d1+d2);
    return d1;
}
int main(){
    cin>>n;
    for (int i=1;i<n;i++){
        int a,b,c;
        cin>>a>>b>>c;
        G[a].push_back(make_pair(b,c));
        G[b].push_back(make_pair(a,c));
    }
    dfs(1,-1);//从节点1开始搜索,没有父节点,所以传-1
    cout<<ans<<endl;
    return 0;
}

网络延时 AC:

#include<iostream>
#include<vector>
using namespace std;
const int N=2e4+5;
int n,m,ans;
vector<int>G[N];
int dfs(int u,int father){
    int d1=0,d2=0;
    for(auto t:G[u]){
        if(t==father) continue;
        int d=dfs(t,u)+1;
        if(d>=d1) d2=d1,d1=d;
        else if(d>d2) d2=d;
    }
    ans=max(ans,d1+d2);
    return d1;
}
int main(){
    cin>>n>>m;
    for(int i=2;i<=n;i++){
        int j;cin>>j;
        G[i].push_back(j);
        G[j].push_back(i);
    }
    for(int i=n+1;i<=n+m;i++){
        int j;cin>>j;
        G[i].push_back(j);
        G[j].push_back(i);
    }
    dfs(1,-1);
    cout<<ans<<endl;
    return 0;
}

AcWing 3216. 最小花费

C 国共有 n 个城市,编号 1∼n。

有 n−1 条双向道路,每条道路连接两个城市,任意两个城市之间能互相到达。

小 R 来到 C 国旅行,他共规划了 m 条旅行的路线,第 i 条旅行路线的起点是 si,终点是 ti。

在旅行过程中,小 R 每行走一单位长度的路需要吃一单位的食物。

C 国的食物只能在各个城市中买到,而且不同城市的食物价格可能不同。

然而,小 R 不希望在旅行中为了购买较低价的粮食而绕远路,因此他总会选择最近的路走。

现在,请你计算小 R 规划的每条旅行路线的最小花费是多少。

输入格式

第一行包含 2 个整数 n 和 m。

第二行包含 n 个整数。第 i 个整数 wi 表示城市 i 的食物价格。

接下来 n−1 行,每行包括 3 个整数 u,v,e,表示城市 u 和城市 v 之间有一条长为 e 的双向道路。

接下来 m 行,每行包含 2 个整数 si 和 ti,分别表示一条旅行路线的起点和终点。

输出格式

输出 m 行,分别代表每一条旅行方案的最小花费。

数据范围

前 10% 的评测用例满足:n,m≤20,wi≤20
前 30% 的评测用例满足:n,m≤200
另有 40% 的评测用例满足:一个城市至多与其它两个城市相连
所有评测用例都满足:1≤n,m≤10^5,1≤wi≤10^6,1≤e≤10000

输入样例

6 4
1 7 3 2 5 6
1 2 4
1 3 5
2 4 1
3 5 2
3 6 1
2 5
4 6
6 4
5 6

输出样例

35
16
26
13

样例解释

对于第一条路线,小 R 会经过 2→1→3→5

其中在城市 2 处以 7 的价格购买 4 单位粮食,到城市 1 时全部吃完,并用 1 的价格购买 7 单位粮食,然后到达终点。

  • 26
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值