问题描述
旋转是图像处理的基本操作,在这个问题中,你需要将一个图像逆时针旋转90度。
计算机中的图像表示可以用一个矩阵来表示,为了旋转一个图像,只需要将对应的矩阵旋转即可。
输入格式
输入的第一行包含两个整数n, m,分别表示图像矩阵的行数和列数。
接下来n行每行包含m个整数,表示输入的图像。
输出格式
输出m行,每行包含n个整数,表示原始矩阵逆时针旋转90度后的矩阵。
样例输入
2 3
1 5 3
3 2 4
样例输出
3 4
5 2
1 3
评测用例规模与约定
1 ≤ n, m ≤ 1,000,矩阵中的数都是不超过1000的非负整数。
暴力输出就行,不知道为啥时限那么大…
#include
using namespace std;
const int maxn = 1e3 + 10;
int mx[maxn][maxn];
int main(){
int n,m; cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) cin >> mx[i][j];
}
for (int i = m; i >= 1; i--) {
for (int j = 1; j <= n; j++) {
cout << mx[j][i];
if (j == n) cout << endl;
else cout << ' ';
}
}
return 0;
}
问题描述
给定n个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出。
输入格式
输入的第一行包含一个整数n,表示给定数字的个数。
第二行包含n个整数,相邻的整数之间用一个空格分隔,表示所给定的整数。
输出格式
输出多行,每行包含两个整数,分别表示一个给定的整数和它出现的次数。按出现次数递减的顺序输出。如果两个整数出现的次数一样多,则先输出值较小的,然后输出值较大的。
样例输入
12
5 2 3 3 1 3 4 2 5 2 3 5
样例输出
3 4
2 3
5 3
1 1
4 1
评测用例规模与约定
1 ≤ n ≤ 1000,给出的数都是不超过1000的非负整数。
水题啊,一万种方法,map记录,利用pair里的内置优先级实现。
#include
using namespace std;
map<int, int> m;
vector<pair<int,int> > a;
int main(){
int n; cin >> n;
for (int i = 0; i < n; i++) {
int x; cin >>x;
m[x]++;
}
for (auto it : m) {
a.push_back(make_pair(-it.second, it.first));
}
sort(a.begin(), a.end());
for (int i = 0; i < a.size(); i++) {
cout << a[i].second << ' ' << -a[i].first << endl;
}
return 0;
}
问题描述
有一类节日的日期并不是固定的,而是以“a月的第b个星期c”的形式定下来的,比如说母亲节就定为每年的五月的第二个星期日。
现在,给你a,b,c和y1, y2(1850 ≤ y1, y2 ≤ 2050),希望你输出从公元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"(不包含双引号)。
样例输入
5 2 7 2014 2015
样例输出
2014/05/11
2015/05/10
评测用例规模与约定
所有评测用例都满足:1 ≤ a ≤ 12,1 ≤ b ≤ 5,1 ≤ c ≤ 7,1850 ≤ y1, y2 ≤ 2050。
这题的难度要看从哪个角度入手,我是用了打表的思路,有点坑,从1850年01月01日
到2050年
每一天都预先求出每一天是本月的第几个星期几,然后暴力的查询出 y1 ~ y2
年中符合的天数,其中打表这一块有点复杂,详细看看代码吧,过了后,看了看网上的代码,发现自己sb了,可以直接通过天数 映射出星期数,从而可以求出,具体参考这里
#include
using namespace std;
struct node {
int y,m,d,cnt,wh;
}a[(int) (1e5 + 10)];
bool isrun(int x) {
if ((x % 4 == 0 && x % 100 != 0) || x % 400 == 0) return true;
return false;
}
int run[13] = {0,31,29,31,30,31,30,31,31,30,31,30,31};
int pin[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int c[8];
void init() {
a[0].y = 1850;
a[0].m = 1;a[0].d = 1;a[0].cnt = 1;a[0].wh = 2;
int l = 1;
c[2]++;
while (l < 80000) {
a[l] = a[l - 1];
bool pre_r = isrun(a[l - 1].y);
a[l].d++;
a[l].wh = a[l - 1].wh == 7 ? 1 : a[l - 1].wh + 1;
c[a[l].wh]++;
a[l].cnt = c[a[l].wh];
if (pre_r) {
if (a[l].d > run[a[l].m]) {
memset(c, 0, sizeof c);
c[a[l].wh]++;
a[l].cnt = c[a[l].wh];
a[l].d = 1;
a[l].m++;
if (a[l].m == 13) {
a[l].m = 1;
a[l].y++;
memset(c, 0, sizeof c);
c[a[l].wh]++;
a[l].cnt = c[a[l].wh];
}
}
} else {
if (a[l].d > pin[a[l].m]) {
memset(c, 0, sizeof c);
c[a[l].wh]++;
a[l].cnt = c[a[l].wh];
a[l].d = 1;
a[l].m++;
if (a[l].m == 13) {
memset(c, 0, sizeof c);
c[a[l].wh]++;
a[l].cnt = c[a[l].wh];
a[l].m = 1;
a[l].y++;
}
}
}
l++;
}
}
int vis[3000];
int main(){
init();
int now;
int x, y, z ,y1,y2; cin >> x >> y >> z >> y1 >> y2;
now = y1;
for (int i = 0; i < 80000; i++) {
if (a[i].y > y2 + 1) break;
if (a[i].y < y1) continue;
if (vis[a[i].y]) continue;
if (a[i].y > now && !vis[now]) {
puts("none");
vis[now++] = 1;
}
if (now > y2) break;
if (now == a[i].y && x == a[i].m &&
y == a[i].cnt && z == a[i].wh) {
cout << now << "/";
if (a[i].m < 10) cout << "0" << a[i].m;
else cout << a[i].m;
cout << "/";
if (a[i].d < 10) cout << "0" << a[i].d;
else cout << a[i].d;
cout << endl;
vis[now++] = 1;
}
}
return 0;
}
问题描述
给定一个公司的网络,由n台交换机和m台终端电脑组成,交换机与交换机、交换机与电脑之间使用网络连接。交换机按层级设置,编号为1的交换机为根交换机,层级为1。其他的交换机都连接到一台比自己上一层的交换机上,其层级为对应交换机的层级加1。所有的终端电脑都直接连接到交换机上。
当信息在电脑、交换机之间传递时,每一步只能通过自己传递到自己所连接的另一台电脑或交换机。请问,电脑与电脑之间传递消息、或者电脑与交换机之间传递消息、或者交换机与交换机之间传递消息最多需要多少步。
输入格式
输入的第一行包含两个整数n, m,分别表示交换机的台数和终端电脑的台数。
第二行包含n - 1个整数,分别表示第2、3、……、n台交换机所连接的比自己上一层的交换机的编号。第i台交换机所连接的上一层的交换机编号一定比自己的编号小。
第三行包含m个整数,分别表示第1、2、……、m台终端电脑所连接的交换机的编号。
输出格式
输出一个整数,表示消息传递最多需要的步数。
样例输入
4 2
1 1 3
2 1
样例输出
4
样例说明
样例的网络连接模式如下,其中圆圈表示交换机,方框表示电脑:
其中电脑1与交换机4之间的消息传递花费的时间最长,为4个单位时间。
样例输入
4 4
1 2 2
3 4 4 4
样例输出
4
样例说明
样例的网络连接模式如下:
其中电脑1与电脑4之间的消息传递花费的时间最长,为4个单位时间。
评测用例规模与约定
前30%的评测用例满足:n ≤ 5, m ≤ 5。
前50%的评测用例满足:n ≤ 20, m ≤ 20。
前70%的评测用例满足:n ≤ 100, m ≤ 100。
所有评测用例都满足:1 ≤ n ≤ 10000,1 ≤ m ≤ 10000。
首先说下怎么存数据,这题也可以动态的分配内存,利用指针来存,但是有点麻烦(个人觉得),就用了vector邻接表来存了,
根据题意可以知道,如果把交换机和电脑都看成普通节点,本题的答案类似于求多叉树的最大深度,因为所有的计算机一端只能连交换机,所以用一维数组标记哪些交换机有电脑连接即可(这里要注意记录下个数,有坑),
然后再递归求每个交换机节点的深度,这里用了vis数组标记,可以优化时间,然后像求二叉树最大深度类似,遍历完所有的节点,分类讨论即可,如果该节点只有一个孩子节点(注意,这里有坑),应该考虑该节点是否有电脑相连,如果该节点有多个孩子节点,取前两个最大的即可(这里用了优先队列,可以优化时间),
最后说下,这个数据是真有问题呀,有些数据根本没有考虑到,但是也是100分,比如下面的数据
1 1 1
2 1 1 1
等
#include
using namespace std;
const int maxn = 1e4 + 10;
int have[maxn];
vector<int> ch[maxn];
int deap[maxn];
int vis[maxn];
int find_deap(int x) {
if (vis[x]) return deap[x];
if (ch[x].size() == 0) {
if (have[x]) return 1;
return 0;
}
int d = -1;
for (int i = 0; i < ch[x].size(); i++) {
d = max(d, find_deap(ch[x][i]));
}
vis[x] = 1;
return deap[x] = d + 1;
}
struct node {
int t;
bool operator < (const node &p) const {
return t < p.t;
}
};
int main(){
int n,m; cin >> n >> m;
for (int i = 2; i <= n; i++) {
int x; cin >> x;
ch[x].push_back(i);
}
for (int i = 0; i < m; i++) {
int x; cin >> x; have[x]++;
}
for (int i = 1; i <= n; i++) {
if (vis[i]) continue;
deap[i] = find_deap(i);
}
int res = 0;
for (int i = 1; i <= n; i++) {
if (ch[i].size() == 0) continue;
if (ch[i].size() == 1) {
if (have[i]) res = max(res, deap[i] + 1);
else res = max(res, deap[i]);
}
else {
priority_queue<node> p;
for (int j = 0; j < ch[i].size(); j++) {
p.push((node){deap[ch[i][j]]});
}
int t = p.top().t; p.pop();
t += p.top().t + 2;
if (t > res) {
res = t;
}
}
}
// if (res == 1 && n + m > 2) res++;
cout << res << endl;
return 0;
}
有题可以知道,n,m的最小值都为1,所以答案最少是1,注意下即可
#include
using namespace std;
const int maxn = 1e4 + 10;
int have[maxn];
vector<int> ch[maxn];
int deap[maxn];
int vis[maxn];
int find_deap(int x) {
if (vis[x]) return deap[x];
if (ch[x].size() == 0) {
if (have[x]) return 1;
return 0;
}
int d = -1;
for (int i = 0; i < ch[x].size(); i++) {
d = max(d, find_deap(ch[x][i]));
}
vis[x] = 1;
return deap[x] = d + 1;
}
struct node {
int t;
bool operator < (const node &p) const {
return t < p.t;
}
};
int main(){
int n,m; cin >> n >> m;
for (int i = 2; i <= n; i++) {
int x; cin >> x;
ch[x].push_back(i);
}
for (int i = 0; i < m; i++) {
int x; cin >> x; have[x]++;
}
for (int i = 1; i <= n; i++) {
if (vis[i]) continue;
deap[i] = find_deap(i);
}
int res = 1;
for (int i = 1; i <= n; i++) {
if (ch[i].size() == 0) continue;
if (ch[i].size() == 1) {
if (have[i]) res = max(res, deap[i] + 1);
else res = max(res, deap[i]);
}
else {
priority_queue<node> p;
for (int j = 0; j < ch[i].size(); j++) {
p.push((node){deap[ch[i][j]]});
}
int t = p.top().t; p.pop();
t += p.top().t + 2;
if (t > res) {
res = t;
}
}
}
// if (res == 1 && n + m > 2) res++;
cout << res << endl;
return 0;
}
第五题是基于点分治的,还没学到,题解在这里,待补