first commit
This commit is contained in:
parent
9c29419472
commit
b875e8e62a
|
@ -0,0 +1,52 @@
|
|||
# 丢失的练习册
|
||||
by Xinran Fang
|
||||
|
||||
时间限制: 1000 ms 内存限制: 1800 KB
|
||||
## 问题描述
|
||||
开学了,阳光小学准备给每个学生发放三本练习册。为了方便发放,每本练习册上都印上了学生的学号。然而,运输过程中由于道路的颠簸,原本捆绑整齐的练习册散落一地,司机师傅再将练习册堆叠在一起时,学号已经完全打乱。更糟糕的是,当他清点练习册总数时,发现少了一本,为了尽快弄清楚丢失的是印有哪位学生学号的练习册,司机师傅只好拿出本子,一个个记录每个练习册上的学号。聪明的你能够通过编程的方法找到是印有哪个同学学号的练习册丢失了吗?
|
||||
## 输入格式
|
||||
第1行为学生的总数:N;
|
||||
|
||||
第2到第3N行为司机师傅记录的练习册上的学号;
|
||||
|
||||
注意:没有丢失练习册的学号会出现3次,而丢失练习册的学号只会出现2次。
|
||||
## 输出格式
|
||||
丢失练习册上对应的学号
|
||||
## 输入样例
|
||||
> 3
|
||||
>
|
||||
> 2021001
|
||||
>
|
||||
> 2021001
|
||||
>
|
||||
> 2023002
|
||||
>
|
||||
> 2023003
|
||||
>
|
||||
> 2023002
|
||||
>
|
||||
> 2023003
|
||||
>
|
||||
> 2023002
|
||||
>
|
||||
> 2021001
|
||||
## 输出样例
|
||||
> 2023003
|
||||
## 提示
|
||||
1. 取值范围
|
||||
|
||||
N的取值范围为[1,1×10^6]的整数;
|
||||
|
||||
学生学号的取值范围为[0, 2×10^9]的整数;
|
||||
|
||||
2. 测试样例
|
||||
|
||||
1~3测试样例N<1×10^4;
|
||||
|
||||
4~5测试样例1×10^4<=N<=5×10^5;
|
||||
|
||||
6~10测试样例5×10^5<N<=1×10^6;
|
||||
|
||||
3. 时间和空间
|
||||
|
||||
本道OJ本身并不难,但对程序运行的时间和空间有较为严格的要求,时间需要为O(n),空间为O(1)才能通过所有的测试样例,请同学们从算法效率的角度出发,选择合适的算法。
|
|
@ -0,0 +1,28 @@
|
|||
#include<iostream>
|
||||
using namespace std;
|
||||
int main() {
|
||||
std::ios::sync_with_stdio(false);
|
||||
int a[32] = { 0 };
|
||||
unsigned int n, num, pos, ansnum = 0;
|
||||
int ans[32] = { 0 };
|
||||
cin >> n;
|
||||
//file >> n;
|
||||
for (int i = 0; i < 3 * n - 1; i++) {
|
||||
cin >> num;
|
||||
//file >> num;
|
||||
for (pos = 0; pos < 32; pos++) {
|
||||
if((num>>pos)&1)
|
||||
a[pos] += 1;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if (a[i] % 3) {
|
||||
ans[i] = 1;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 32; i++) {
|
||||
ansnum *= 2;
|
||||
ansnum += ans[31-i];
|
||||
}
|
||||
cout << ansnum;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include<algorithm>
|
||||
#include<stdlib.h>
|
||||
#include<math.h>
|
||||
using namespace std;
|
||||
//fstream file("oj1.txt", ios::in);
|
||||
int pows[10] = { 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
|
||||
int numPos(int num, int pos) {
|
||||
return (num / pows[pos]) % 10;
|
||||
}
|
||||
int main() {
|
||||
//std::ios::sync_with_stdio(false);
|
||||
int a[10][10]={0};
|
||||
int n, num,pos,ansnum=0;
|
||||
int ans[10];
|
||||
cin >> n;
|
||||
//file >> n;
|
||||
for (int i = 0; i < 3*n-1; i++) {
|
||||
cin >> num;
|
||||
//file >> num;
|
||||
for (pos = 0; pos < 10; pos++) {
|
||||
a[numPos(num, pos)][pos] += 1;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int j = 0; j < 10; j++) {
|
||||
if (a[j][i] % 3) {
|
||||
ans[9-i] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ansnum *= 10;
|
||||
ansnum += ans[i];
|
||||
}
|
||||
cout << ansnum;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#include<stdio.h>
|
||||
int cost[2050][2050];
|
||||
// broadcast_cost[i][j]=cost[j][i]
|
||||
int tensor[2050][32];
|
||||
int prefix_sum[2050][32];
|
||||
int max[32];
|
||||
int n,k;
|
||||
int broadcast_cost(int i,int j){
|
||||
int cost=1;
|
||||
for(int t=0;t<=k-3;t++){
|
||||
if(prefix_sum[j+1][t]-prefix_sum[i][t])
|
||||
cost*=max[t];
|
||||
}
|
||||
cost*=tensor[i][k-2];
|
||||
cost*=tensor[j][k-1];
|
||||
return cost;
|
||||
}
|
||||
int main(){
|
||||
scanf("%d%d",&n,&k);
|
||||
for(int i=0;i<n;i++){
|
||||
for(int j=0;j<k;j++){
|
||||
scanf("%d",&tensor[i][j]);
|
||||
}
|
||||
cost[i][i]=0;
|
||||
}
|
||||
|
||||
for(int t=0;t<=k-3;t++){
|
||||
int sum=0;
|
||||
for(int i=0;i<n;i++){
|
||||
prefix_sum[i][t]=sum;
|
||||
if(tensor[i][t]!=1){
|
||||
max[t]=tensor[i][t];
|
||||
sum++;
|
||||
}
|
||||
}
|
||||
prefix_sum[n][t]=sum;
|
||||
}
|
||||
for(int i=0;i<n;i++){
|
||||
for(int j=i+1;j<n;j++){
|
||||
cost[j][i]=broadcast_cost(i,j);
|
||||
}
|
||||
}
|
||||
for(int t=1;t<n;t++){
|
||||
for(int i=0;i+t<n;i++){
|
||||
int min=2147483647;
|
||||
for(int j=i;j<i+t;j++){
|
||||
if(cost[i][j]+cost[j+1][i+t]+cost[i+t][i]*tensor[j][k-1]<min){
|
||||
min=cost[i][j]+cost[j+1][i+t]+cost[i+t][i]*tensor[j][k-1];
|
||||
}
|
||||
}
|
||||
cost[i][i+t]=min;
|
||||
}
|
||||
}
|
||||
printf("%d",cost[0][n-1]);
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
# 军训排队
|
||||
by 郑凯俐
|
||||
|
||||
时间限制: 1000 ms内存限制: 2000 KB
|
||||
## 问题描述
|
||||
军训时需要将所有同学(包括教官)排成一队,一开始只有教官(编号为1)排在第一个,之后教官会发出如下三种命令:
|
||||
|
||||
1 x y 编号为y的同学入队,排在编号为x的同学的后面,若要排在队首,则用0表示x
|
||||
|
||||
2 x 编号为x的同学报告其后面的同学编号,若要报告队首同学的编号,则用0表示x,若x在队尾,则报告0
|
||||
|
||||
3 x 编号为x的同学出队
|
||||
|
||||
要求对于每次命令2,都输出报告同学后面同学的编号,并最后从头到尾输出队列中同学的编号。
|
||||
## 输入格式
|
||||
第一行为一个正整数N,表示总共有几条命令
|
||||
|
||||
接下来N行中,每行表示一个命令;每行命令中,数字之间用空格隔开
|
||||
## 输出格式
|
||||
对于每次命令2,都输出一个编号,用换行隔开
|
||||
|
||||
最后从头到尾输出队列,用换行隔开
|
||||
## 输入样例
|
||||
> // 例如上图中的命令对应以下输入
|
||||
>
|
||||
> 7
|
||||
>
|
||||
> 1 1 2
|
||||
>
|
||||
> 1 1 3
|
||||
>
|
||||
> 2 3
|
||||
>
|
||||
> 1 2 4
|
||||
>
|
||||
> 3 1
|
||||
>
|
||||
> 1 0 5
|
||||
>
|
||||
> 2 4
|
||||
## 输出样例
|
||||
> // 例如上图中的命令会产生以下输出
|
||||
>
|
||||
> 2
|
||||
>
|
||||
> 0
|
||||
>
|
||||
> 5
|
||||
>
|
||||
> 3
|
||||
>
|
||||
> 2
|
||||
>
|
||||
> 4
|
||||
## 提示
|
||||
1. 同学编号为小于100000的正整数
|
||||
|
||||
2. 命令的条数N为小于200000的正整数
|
||||
|
||||
3. 队列中没有人时不会出现命令2和命令3
|
|
@ -0,0 +1,97 @@
|
|||
#include<iostream>
|
||||
#include<map>
|
||||
using namespace std;
|
||||
struct node {
|
||||
int no;
|
||||
struct node* pnext;
|
||||
};
|
||||
struct linkedList {
|
||||
map<int, node*> index;
|
||||
struct node head;
|
||||
struct node tail;
|
||||
linkedList();
|
||||
void insertAfter(int no, int nextno);
|
||||
int reportNext(int no);
|
||||
void deleteNode(int no);
|
||||
void printAll();
|
||||
};
|
||||
linkedList::linkedList() {
|
||||
head.no = 0;
|
||||
head.pnext = &tail;
|
||||
tail.no = 0;
|
||||
tail.pnext = nullptr;
|
||||
}
|
||||
void linkedList::insertAfter(int no, int nextno) {
|
||||
node* next = new node;
|
||||
next->no = nextno;
|
||||
node* now = &head;
|
||||
while (now->pnext != nullptr) {
|
||||
if (now->no == no) {
|
||||
next->pnext = now->pnext;
|
||||
now->pnext = next;
|
||||
index[nextno] = next;
|
||||
return;
|
||||
}
|
||||
now = now->pnext;
|
||||
}
|
||||
}
|
||||
int linkedList::reportNext(int no) {
|
||||
if (no == 0) {
|
||||
return head.pnext->no;
|
||||
}
|
||||
else {
|
||||
return index[no]->pnext->no;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void linkedList::deleteNode(int no) {
|
||||
node* now = &head;
|
||||
node* tmpptr;
|
||||
while (now->pnext != nullptr) {
|
||||
if (now->pnext->no == no) {
|
||||
tmpptr = now->pnext->pnext;
|
||||
delete now->pnext;
|
||||
now->pnext = tmpptr;
|
||||
return;
|
||||
}
|
||||
now = now->pnext;
|
||||
}
|
||||
}
|
||||
void linkedList::printAll() {
|
||||
node* now = &head;
|
||||
node* tmpptr;
|
||||
while (now->pnext != nullptr) {
|
||||
if (now->no != 0) {
|
||||
cout << now->no << endl;
|
||||
}
|
||||
now = now->pnext;
|
||||
}
|
||||
}
|
||||
int main() {
|
||||
std::ios::sync_with_stdio(false);
|
||||
linkedList list;
|
||||
int choice;
|
||||
int total;
|
||||
int x;
|
||||
int y;
|
||||
cin >> total;
|
||||
list.insertAfter(0, 1);
|
||||
for (int i = 0; i < total; i++) {
|
||||
cin >> choice;
|
||||
if (choice == 1) {
|
||||
cin >> x;
|
||||
cin >> y;
|
||||
list.insertAfter(x, y);
|
||||
}
|
||||
else if (choice == 2) {
|
||||
cin >> x;
|
||||
cout << list.reportNext(x) << endl;
|
||||
}
|
||||
else if (choice == 3) {
|
||||
cin >> x;
|
||||
list.deleteNode(x);
|
||||
}
|
||||
}
|
||||
list.printAll();
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#include<stdio.h>
|
||||
#include<utility>
|
||||
#pragma warning(disable:4996)
|
||||
using namespace std;
|
||||
int main() {
|
||||
pair<int,int> mainMap[100000];
|
||||
int choice;
|
||||
int total;
|
||||
int x;
|
||||
int y;
|
||||
scanf("%d", &total);
|
||||
mainMap[0] = { 1,1 };
|
||||
mainMap[1] = { 0,0 };
|
||||
for (int i = 0; i < total; i++) {
|
||||
scanf("%d", &choice);
|
||||
if (choice == 1) {
|
||||
scanf("%d", &x);
|
||||
scanf("%d", &y);
|
||||
mainMap[y] = { x,mainMap[x].second };
|
||||
mainMap[mainMap[x].second].first = y;
|
||||
mainMap[x].second = y;
|
||||
}
|
||||
else if (choice == 2) {
|
||||
scanf("%d", &x);
|
||||
printf("%d\n", mainMap[x].second);
|
||||
}
|
||||
else if (choice == 3) {
|
||||
scanf("%d", &x);
|
||||
mainMap[mainMap[x].first].second = mainMap[x].second;
|
||||
mainMap[mainMap[x].second].first = mainMap[x].first;
|
||||
}
|
||||
}
|
||||
int no = 0;
|
||||
do {
|
||||
no = mainMap[no].second;
|
||||
if (no != 0)
|
||||
printf("%d\n", no);
|
||||
} while (no != 0);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#include<stdio.h>
|
||||
#include<unordered_map>
|
||||
#pragma warning(disable:4996)
|
||||
using namespace std;
|
||||
int main() {
|
||||
unordered_map<int, pair<int, int>> mainMap;
|
||||
int choice;
|
||||
int total;
|
||||
int x;
|
||||
int y;
|
||||
scanf("%d", &total);
|
||||
mainMap[0] = { 1,1 };
|
||||
mainMap[1] = { 0,0 };
|
||||
for (int i = 0; i < total; i++) {
|
||||
scanf("%d", &choice);
|
||||
if (choice == 1) {
|
||||
scanf("%d", &x);
|
||||
scanf("%d", &y);
|
||||
mainMap[y] = { x,mainMap[x].second };
|
||||
mainMap[mainMap[x].second].first = y;
|
||||
mainMap[x].second = y;
|
||||
}
|
||||
else if (choice == 2) {
|
||||
scanf("%d", &x);
|
||||
printf("%d\n", mainMap[x].second);
|
||||
}
|
||||
else if (choice == 3) {
|
||||
scanf("%d", &x);
|
||||
mainMap[mainMap[x].first].second = mainMap[x].second;
|
||||
mainMap[mainMap[x].second].first = mainMap[x].first;
|
||||
mainMap.erase(x);
|
||||
}
|
||||
}
|
||||
int no = 0;
|
||||
do {
|
||||
no = mainMap[no].second;
|
||||
if (no != 0)
|
||||
printf("%d\n", no);
|
||||
} while (no != 0);
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
# 比武
|
||||
by 郑瑜
|
||||
|
||||
时间限制: 1000 ms 内存限制: 5000 KB
|
||||
## 问题描述
|
||||
N个士兵站成一列,每个士兵都有一个武力值。对于队伍中任意两个士兵X和Y,如果他们在队伍中相邻,或者他们之间没有士兵的武力值严格大于X和Y的武力值中的较小值,那么他们需要进行一次比武。请计算总共需要进行几次比武。
|
||||
## 输入格式
|
||||
第一行:一个整数N,代表士兵的总数
|
||||
|
||||
第2到第N+1行:每行是一个整数,表示队伍中从头至尾每个士兵的武力值
|
||||
## 输出格式
|
||||
一个整数,表示比武的次数
|
||||
## 输入样例
|
||||
输入样例1:
|
||||
> 8
|
||||
>
|
||||
> 2
|
||||
>
|
||||
> 7
|
||||
>
|
||||
> 1
|
||||
>
|
||||
> 6
|
||||
>
|
||||
> 5
|
||||
>
|
||||
> 3
|
||||
>
|
||||
> 4
|
||||
>
|
||||
> 2
|
||||
|
||||
输入样例2:
|
||||
> 5
|
||||
>
|
||||
> 4
|
||||
>
|
||||
> 2
|
||||
>
|
||||
> 2
|
||||
>
|
||||
> 2
|
||||
>
|
||||
> 5
|
||||
## 输出样例
|
||||
输出样例1:
|
||||
> 9
|
||||
|
||||
输出样例2:
|
||||
> 10
|
||||
## 提示
|
||||
请使用scanf/printf实现输入/输出
|
||||
|
||||
比武的次数可能很大,超过int的范围
|
||||
|
||||
不同士兵的武力值可能相等
|
||||
|
||||
可能用到的结论:对于任意士兵Z,排在Z前面且武力值比Z小的士兵不会和排在Z后面的士兵比武
|
||||
|
||||
对于全部的测试点,保证1<=每个士兵的武力值<2^31
|
||||
|
||||
1-2测试样例:N<=1×10^3
|
||||
|
||||
3-4测试样例:1×10^3<N<=1×10^4
|
||||
|
||||
5-10测试样例:1×10^4<N<=5×10^5
|
|
@ -0,0 +1,49 @@
|
|||
#include<stdio.h>
|
||||
#pragma warning(disable:4996)
|
||||
int studentStack[500010] = { 0 };
|
||||
int weight[500010] = { 0 };
|
||||
int main() {
|
||||
|
||||
int sum = 0;
|
||||
int top = -1;
|
||||
int tmpstu;
|
||||
int times[2] = { 1,1 };
|
||||
long long int competitionSum = 0;
|
||||
scanf("%d", &sum);
|
||||
for (int i = 0; i < sum; i++) {
|
||||
scanf("%d", &tmpstu);
|
||||
for (int i = top; i >= -1; i--) {
|
||||
if (i==-1) {
|
||||
top = i + 1;
|
||||
studentStack[top] = tmpstu;
|
||||
weight[top] = 1;
|
||||
break;
|
||||
}
|
||||
else if (studentStack[i] > tmpstu) {
|
||||
top = i + 1;
|
||||
studentStack[top] = tmpstu;
|
||||
weight[top] = 1;
|
||||
competitionSum+=1;
|
||||
break;
|
||||
}
|
||||
else if (studentStack[i] == tmpstu) {
|
||||
if (i == 0) {
|
||||
top = i;
|
||||
competitionSum += weight[top];
|
||||
weight[top] += 1;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
top = i;
|
||||
competitionSum += weight[top] + 1;
|
||||
weight[top] += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
competitionSum += weight[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%lld", competitionSum);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
# 缺损二叉树
|
||||
by 庾湫镆
|
||||
|
||||
时间限制: 1000 ms 内存限制: 1000 KB
|
||||
|
||||
## 问题描述
|
||||
输入给定一系列缺损点,将一棵无限深度的满二叉树进行重新编号,编号方式为从1开始逐行从左至右顺序编号,缺损点得到编号后,其子树被删去,后续编号中该子树的结点跳过不编号,编号后的树被称为“缺损二叉树”。例如下图为缺损点为{5,6,9}的缺损二叉树的一部分(下方可无限延长),红色数字标注了缺损点,其下方灰色子树被删去。对于输入给定的目标编号,输出缺损二叉树上根节点到目标结点的路径,该路径用经过的所有结点的编号表示。下图中,蓝色表示根结点到目标结点15的路径,路径用途径结点编号{1,3,7,10,15}表示。
|
||||
## 输入格式
|
||||
第一行为两个整数N和M,N表示缺损点数目,M表示目标点的数目。
|
||||
|
||||
第二行为N个缺损点的编号,按从小到大顺序排列。
|
||||
|
||||
第三行为M个目标点的编号,按从小到大顺序排列。
|
||||
|
||||
下方给出的输入样例表示缺损点为{5,6,9},目标点为{3,9,15,22}。
|
||||
## 输出格式
|
||||
每一行输出根节点到一个目标点的最短路径,路径用途径节点编号表示。
|
||||
|
||||
如果该路径不存在,则输出0。
|
||||
|
||||
共输出M行。
|
||||
## 输入样例
|
||||
>3 4
|
||||
>
|
||||
>5 6 9
|
||||
>
|
||||
>3 9 15 22
|
||||
## 输出样例
|
||||
1 3
|
||||
1 2 4 9
|
||||
1 3 7 10 15
|
||||
1 3 7 10 14 22
|
||||
## 提示
|
||||
题目假定缺损点及目标点数目不超过100个,目标节点编号均小于2^32。
|
||||
|
||||
对本题,可以根据题目要求逐行构造该缺损二叉树。对于当前行,记录所有非缺损点,在下一行依次构造子节点,并排除缺损点,直到构造到目标节点为止。利用构造节点时记录的父亲节点编号,可以从目标节点搜索到回到根节点的路径,将该路径翻转,即可得到所求路径。
|
||||
|
||||
上述方法在目标节点编号过大时会占用过多内存,事实上,若某棵子树或树中的某连续部分不存在缺损点,可以不必将其每个节点均储存在内存中。你可以自行设计省略表示方法以满足性能要求。
|
|
@ -0,0 +1,86 @@
|
|||
#include <stdio.h>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
struct layer{
|
||||
unsigned long long int begin;
|
||||
unsigned long long int end;
|
||||
vector<unsigned int> newDeads;
|
||||
};
|
||||
layer layers[135];
|
||||
int currentLayer = 0;
|
||||
int layerNum;
|
||||
int currentDead = 0;
|
||||
int deadNum, targetNum;
|
||||
unsigned long long int limit = 4294967295;
|
||||
unsigned long long int deads[100];
|
||||
unsigned long long int path[135];
|
||||
int main(){
|
||||
scanf("%d %d", &deadNum, &targetNum);
|
||||
for (int i = 0; i < deadNum; i++){
|
||||
scanf("%llu", &deads[i]);
|
||||
}
|
||||
long long int prevEnd=1, prevLen=1;
|
||||
if(deads[0]!=1){
|
||||
layers[0].begin=1;
|
||||
layers[0].end=1;
|
||||
}
|
||||
else{
|
||||
layers[0].begin=1;
|
||||
layers[0].end=1;
|
||||
prevLen=0;
|
||||
}
|
||||
for (currentLayer = 1; currentLayer < 135; currentLayer++){
|
||||
if (prevEnd >= limit || (prevLen == 0&¤tLayer!=0)){
|
||||
currentLayer--;
|
||||
break;
|
||||
}
|
||||
layers[currentLayer].begin = prevEnd + 1;
|
||||
layers[currentLayer].end = layers[currentLayer].begin + prevLen * 2 - 1;
|
||||
if (layers[currentLayer].end > limit){
|
||||
layers[currentLayer].end = limit;
|
||||
break;
|
||||
}
|
||||
prevEnd = layers[currentLayer].end;
|
||||
prevLen = layers[currentLayer].end - layers[currentLayer].begin + 1;
|
||||
for (currentDead=0; currentDead < deadNum; currentDead++){
|
||||
if (deads[currentDead] <= layers[currentLayer].end&&deads[currentDead] >= layers[currentLayer].begin){
|
||||
prevLen--;
|
||||
layers[currentLayer].newDeads.push_back(deads[currentDead]);
|
||||
}
|
||||
}
|
||||
}
|
||||
layerNum = currentLayer;
|
||||
for (int i = 0; i < targetNum; i++){
|
||||
unsigned long long int target;
|
||||
scanf("%llu", &target);
|
||||
int found=0;
|
||||
for (int i = 0; i <= layerNum; i++){
|
||||
if (target <= layers[i].end){
|
||||
path[i] = target;
|
||||
unsigned long long int tmp = target;
|
||||
for (int j = i; j > 0; j--){
|
||||
tmp = (tmp - layers[j].begin) / 2 + layers[j - 1].begin;
|
||||
for (auto i = layers[j - 1].newDeads.begin(); i < layers[j - 1].newDeads.end(); i++){
|
||||
if (*i <= tmp){
|
||||
tmp++;
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
path[j - 1] = tmp;
|
||||
}
|
||||
for (int t = 0; t <= i; t++){
|
||||
printf("%llu ", path[t]);
|
||||
}
|
||||
printf("\n");
|
||||
found=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found){
|
||||
printf("0\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
# 信息传递
|
||||
by Chen Ning
|
||||
|
||||
时间限制: 1000 ms 内存限制: 6000 KB
|
||||
## 问题描述
|
||||
某组织在执行任务时需要进行信息传递,为保证信息传递的安全性,每个节点只能向特定的某些节点发送消息,已知有N个节点,初始信息由0号节点开始发送,现在系统的设计师需要确认所设计的连接方式能否使得所有节点最终都收到0号节点发送的消息。为了保证系统的鲁棒性,系统设计师还需要考虑若有信道损坏是否会影响信息的传递。具体来说,给定M条可能毁坏的信道,需要依次考虑只有一条信道被毁坏时是否所有节点仍能收到0号节点发送的信息。下面是一幅与输入输出样例对应的示意图,绿色节点能收到0号节点发送的信息,橙色节点则无法收到。
|
||||
## 输入格式
|
||||
输入共N+M+1行
|
||||
|
||||
第一行为两个正整数,第一个正整数N表示节点总数,第二个正整数M表示可能被破坏的信道数
|
||||
|
||||
接下来的N行依次给出从0号节点到N-1号节点能发送消息的节点;每行第一个数n表示该节点能传递消息的节点个数,后面n个数表示能传递消息的节点编号,同一行的数之间用空格分隔。
|
||||
|
||||
接下来的M行对应M个可能毁坏的信道,每行两个数i j,用空格分隔,表示从节点i到节点j的信道毁坏。
|
||||
## 输出格式
|
||||
输出为M+1行,每行一个正整数,第一行对应原始情况,后面M行依次对应M条信道毁坏后的情况。若对应情况下所有节点都能收到0号节点发送的消息,则输出1,反之输出0。
|
||||
## 输入样例
|
||||
> 4 2
|
||||
>
|
||||
> 2 1 2
|
||||
>
|
||||
> 2 2 3
|
||||
>
|
||||
> 0
|
||||
>
|
||||
> 1 0
|
||||
>
|
||||
> 0 1
|
||||
>
|
||||
> 0 2
|
||||
## 输出样例
|
||||
> 1
|
||||
>
|
||||
> 0
|
||||
>
|
||||
> 1
|
||||
## 提示
|
||||
1. 测试样例情况:
|
||||
|
||||
1-4测试样例:N<2^10,M=0
|
||||
|
||||
5-7测试样例:N<2^16,M=0
|
||||
|
||||
8-10测试样例:N<2^16,M<2^16
|
||||
|
||||
对于所有测试样例,边数E<2^20
|
||||
|
||||
2. 图中无自环、重边
|
|
@ -0,0 +1,177 @@
|
|||
#include <stdio.h>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
unsigned short *neighbors[65540];
|
||||
unsigned short bfsGraph[65540] = {0}; // index: to value: from
|
||||
unsigned short outDegrees[65540] = {0};
|
||||
unsigned short inDegrees[65540] = {0};
|
||||
int nodeNum, destroyed;
|
||||
template <typename T>
|
||||
class Queue
|
||||
{
|
||||
public:
|
||||
Queue(int max);
|
||||
Queue(Queue &q);
|
||||
~Queue();
|
||||
bool isEmpty();
|
||||
void in(T t);
|
||||
T out();
|
||||
|
||||
private:
|
||||
T *list;
|
||||
int max, front, tail;
|
||||
bool empty = true;
|
||||
};
|
||||
template <typename T>
|
||||
Queue<T>::Queue(int max)
|
||||
{
|
||||
list = new T[this->max = max];
|
||||
front = 0;
|
||||
tail = -1;
|
||||
}
|
||||
template <typename T>
|
||||
Queue<T>::Queue(Queue &q)
|
||||
{
|
||||
list = new T[max = q.max];
|
||||
front = 0;
|
||||
tail = -1;
|
||||
for (int i = front; (i > front && tail < front) || i <= tail; (i++) % max)
|
||||
{
|
||||
list[++tail] = q.list[i];
|
||||
}
|
||||
if (!q.isEmpty)
|
||||
empty == false;
|
||||
}
|
||||
template <typename T>
|
||||
Queue<T>::~Queue()
|
||||
{
|
||||
delete[] list;
|
||||
}
|
||||
template <typename T>
|
||||
bool Queue<T>::isEmpty()
|
||||
{
|
||||
return empty;
|
||||
}
|
||||
template <typename T>
|
||||
void Queue<T>::in(T t)
|
||||
{
|
||||
if (tail == (front - 1 + max) % max && !empty)
|
||||
{
|
||||
throw 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tail++;
|
||||
tail = tail % max;
|
||||
list[tail] = t;
|
||||
empty = false;
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
T Queue<T>::out()
|
||||
{
|
||||
if (empty)
|
||||
{
|
||||
throw 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (front == tail)
|
||||
empty = true;
|
||||
int tmp = front;
|
||||
front++;
|
||||
front = front % max;
|
||||
return list[tmp];
|
||||
}
|
||||
}
|
||||
bool bfs(int nodeNum, unsigned short delFrom = 0, unsigned short delTo = 0, bool output = false)
|
||||
{
|
||||
Queue<unsigned short> q(65540);
|
||||
bool reached[65540] = {0};
|
||||
q.in(0);
|
||||
reached[0] = true;
|
||||
while (1)
|
||||
{
|
||||
if (q.isEmpty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
int current = q.out();
|
||||
for (int i = 0; i < outDegrees[current]; i++)
|
||||
{
|
||||
if (current == delFrom && neighbors[current][i] == delTo)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (reached[neighbors[current][i]])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
reached[neighbors[current][i]] = true;
|
||||
q.in(neighbors[current][i]);
|
||||
if (output)
|
||||
{
|
||||
bfsGraph[neighbors[current][i]] = current;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < nodeNum; i++)
|
||||
{
|
||||
if (!reached[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
scanf("%d %d", &nodeNum, &destroyed);
|
||||
for (int i = 0; i < nodeNum; i++)
|
||||
{
|
||||
int outDegNum;
|
||||
scanf("%d", &outDegNum);
|
||||
int currentNode = i;
|
||||
outDegrees[i] = outDegNum;
|
||||
neighbors[i] = new unsigned short[outDegNum];
|
||||
for (int i = 0; i < outDegNum; i++)
|
||||
{
|
||||
int nodeNo;
|
||||
scanf("%d", &nodeNo);
|
||||
inDegrees[nodeNo] += 1;
|
||||
neighbors[currentNode][i] = nodeNo;
|
||||
}
|
||||
}
|
||||
bool connected = bfs(nodeNum, 0, 0, true);
|
||||
if (connected)
|
||||
{
|
||||
printf("1\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < destroyed + 1; i++)
|
||||
printf("0\n");
|
||||
return 0;
|
||||
}
|
||||
for (int i = 0; i < destroyed; i++)
|
||||
{
|
||||
int from, to;
|
||||
scanf("%d %d", &from, &to);
|
||||
if (bfsGraph[to] != from)
|
||||
{
|
||||
printf("1\n");
|
||||
}
|
||||
else if (inDegrees[to] <= 1)
|
||||
{
|
||||
printf("0\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bfs(nodeNum, from, to, false))
|
||||
printf("1\n");
|
||||
else
|
||||
printf("0\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#include<stdio.h>
|
||||
int main(){
|
||||
int inDegree[65540]={0};
|
||||
int node, destroy;
|
||||
scanf("%d %d",&node,&destroy);
|
||||
for(int i=0;i<node;i++){
|
||||
int outDegNum;
|
||||
scanf("%d",&outDegNum);
|
||||
for(int i=0;i<outDegNum;i++){
|
||||
int nodeNo;
|
||||
scanf("%d",&nodeNo);
|
||||
inDegree[nodeNo]+=1;
|
||||
}
|
||||
}
|
||||
int canReach=1;
|
||||
for(int i=1;i<node;i++){
|
||||
if(inDegree[i]==0){
|
||||
canReach=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("%d\n",canReach);
|
||||
if(!canReach){
|
||||
for(int i=0;i<destroy;i++)
|
||||
printf("0\n");
|
||||
return 0;
|
||||
}
|
||||
for(int i=0;i<destroy;i++){
|
||||
int from,to;
|
||||
scanf("%d %d",&from,&to);
|
||||
if(inDegree[to]>1){
|
||||
printf("1\n");
|
||||
}
|
||||
else if(to==0)
|
||||
{
|
||||
printf("1\n");
|
||||
}
|
||||
else{
|
||||
printf("0\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
# 跳跳乐
|
||||
by 陈宇豪
|
||||
|
||||
时间限制: 2000 ms 内存限制: 1500 KB
|
||||
## 问题描述
|
||||
有一系列相邻的台阶,每级台阶具有不同的高度,台阶间的水平距离相等,如图所示
|
||||
|
||||
有一只青蛙在不同台阶之间跳跃,设青蛙可以跳跃的最长水平距离为K个台阶,最大的垂直距离为H(需要注意的是,为简化问题,垂直距离只需考虑跳跃起点和终点的高度差,不需要考虑途中经过的台阶高度和起点的高度差),以上图为例,若K=5,H=2,则青蛙可以从当前位置跳跃到编号为{0, 3, 6}的三个台阶,因为这三个台阶与当前台阶的水平距离均不大于5,且垂直距离的绝对值分别为{2, 1, 1},均不大于2。
|
||||
|
||||
现在总共有M个连续台阶,并给定每个台阶的高度,试求青蛙一共可能在多少对台阶间跳跃?
|
||||
## 输入格式
|
||||
输入为两行
|
||||
|
||||
第一行为三个整数,分别为台阶数量M,青蛙可以跳跃的最长水平距离K,可以跳跃的最大垂直距离H
|
||||
|
||||
第二行为M个整数,依次为各个台阶的高度
|
||||
## 输出格式
|
||||
输出为一个整数,为青蛙可以跳跃的台阶对数
|
||||
## 输入样例
|
||||
> 9 5 2
|
||||
>
|
||||
> 6 8 5 7 4 3 9 2 10
|
||||
## 输出样例
|
||||
> 14
|
||||
>
|
||||
> // 可跳跃的台阶对编号分别为(0, 1), (0, 2), (0, 3), (0, 4), (1, 3), (1, 6), (2, 3), (2, 4), (2, 5), (3, 6), (4, 5), (4, 7), (5, 7), (6, 8)
|
||||
## 提示
|
||||
输入数据范围:
|
||||
|
||||
M<1×10^5,K<5×10^4,H<2^31,每级台阶的高度也小于2^31
|
||||
|
||||
相邻两个台阶间的水平距离均相等且值为1,任意两个台阶的高度均不相等
|
|
@ -0,0 +1,37 @@
|
|||
#include<stdio.h>
|
||||
#include<vector>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
int main(){
|
||||
long long int m,k,h;
|
||||
long long int sum=0;
|
||||
scanf("%lld %lld %lld",&m,&k,&h);
|
||||
int *steps=new int[m];
|
||||
for(int i=0;i<m;i++){
|
||||
scanf("%d",&steps[i]);
|
||||
}
|
||||
vector<int> insightSteps;
|
||||
for(long long int i=0;i<k&&i<m;i++){
|
||||
insightSteps.push_back(steps[i]);
|
||||
}
|
||||
sort(insightSteps.begin(),insightSteps.end());
|
||||
for(long long int i=0;i<m;i++){
|
||||
insightSteps.erase(find(insightSteps.begin(),insightSteps.end(),steps[i]));
|
||||
auto ip=insightSteps.begin();
|
||||
if(i+k<m){
|
||||
ip=lower_bound(insightSteps.begin(),insightSteps.end(),steps[i+k]);
|
||||
insightSteps.insert(ip,steps[i+k]);
|
||||
}
|
||||
long long int lowest=steps[i]-h;
|
||||
lowest=lowest<0?0:lowest;
|
||||
long long int highest=steps[i]+h;
|
||||
highest=highest>2147483647?2147483647:highest;
|
||||
auto lb=lower_bound(insightSteps.begin(),insightSteps.end(),lowest);
|
||||
auto ub=upper_bound(insightSteps.begin(),insightSteps.end(),highest);
|
||||
sum+=ub-lb;
|
||||
}
|
||||
printf("%lld\n",sum);
|
||||
delete[] steps;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#include<stdio.h>
|
||||
int main(){
|
||||
int p,n,m;
|
||||
double c[10010],b[10010],a[10010],beta[10010],l[10010],z[10010];
|
||||
scanf("%d",&p);
|
||||
if(p==5){
|
||||
printf("先摆了\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
scanf("%d %d",&n,&m);
|
||||
for(int i=1;i<=n-1;i++){
|
||||
scanf("%lf",&c[i]);
|
||||
}
|
||||
for(int i=1;i<=n;i++){
|
||||
scanf("%lf",&b[i]);
|
||||
}
|
||||
for(int i=2;i<=n;i++){
|
||||
scanf("%lf",&a[i]);
|
||||
}
|
||||
beta[1]=b[1];
|
||||
for(int i=2;i<=n;i++){
|
||||
l[i]=a[i]/beta[i-1];
|
||||
beta[i]=b[i]-l[i]*c[i-1];
|
||||
}
|
||||
for(int i=0;i<m;i++){
|
||||
for(int i=1;i<=n;i++){
|
||||
scanf("%lf",&z[i]);
|
||||
}
|
||||
a[1]=z[1];
|
||||
for(int i=2;i<=n;i++){
|
||||
a[i]=z[i]-l[i]*a[i-1];
|
||||
}
|
||||
b[n]=a[n]/beta[n];
|
||||
for(int i=n-1;i>=1;i--){
|
||||
b[i]=(a[i]-c[i]*b[i+1])/beta[i];
|
||||
}
|
||||
for(int i=1;i<=n-1;i++){
|
||||
printf("%.4f ",b[i]);
|
||||
}
|
||||
printf("%.4f\n",b[n]);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
#include<stdio.h>
|
||||
#include<math.h>
|
||||
// using newton interpolation
|
||||
int main(){
|
||||
int n,m;
|
||||
double x[100],y[100];
|
||||
double t[100];
|
||||
double xt;
|
||||
scanf("%d",&n);
|
||||
scanf("%d",&m);
|
||||
for(int i=0;i<n;i++){
|
||||
scanf("%lf %lf",&x[i],&y[i]);
|
||||
for(int j=0;j<i;j++){
|
||||
// if points are too close, just keep one of them.
|
||||
if(fabs(x[i]-x[j])<1e-6){
|
||||
i--;
|
||||
n--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// newton interpolation
|
||||
for(int i=0;i<n;i++){
|
||||
for(int j=i-1;j>=0;j--){
|
||||
double p=1;
|
||||
for(int k=j-1;k>=0;k--){
|
||||
p=p*(x[i]-x[k]);
|
||||
}
|
||||
y[i]=y[i]-p*t[j];
|
||||
}
|
||||
double p=1;
|
||||
for(int k=i-1;k>=0;k--){
|
||||
p=p*(x[i]-x[k]);
|
||||
}
|
||||
/*
|
||||
if value is precise enough then higher terms are not necessary (sometimes even
|
||||
troublesome, when x[k] is too close to x[0], x[1],...,x[k-1] (distance < 1)
|
||||
then p=(x[k]-x[0])*(x[k]-x[1])*...*(x[k]-x[k-1]) is too small, this will result
|
||||
in a super large t[k] even when the residual error of a k-1 degree polynomial
|
||||
is small enough.)
|
||||
*/
|
||||
if(fabs(y[i])<1e-9){
|
||||
y[i]=0;
|
||||
}
|
||||
t[i]=y[i]/p;
|
||||
}
|
||||
int k=0;
|
||||
for(int i=0;i<n;i++){
|
||||
// if a coefficient is too small, then regard it as zero.
|
||||
if(fabs(t[i])>1e-6){
|
||||
k=i;
|
||||
}
|
||||
}
|
||||
// degree of the polynomial
|
||||
printf("%d\n",k);
|
||||
n=k+1;
|
||||
for(int i=0;i<m;i++){
|
||||
scanf("%lf",&xt);
|
||||
double yt=0;
|
||||
double p=1;
|
||||
for(int j=0;j<n;j++){
|
||||
yt+=t[j]*p;
|
||||
p*=(xt-x[j]);
|
||||
}
|
||||
printf("%lf\n",yt);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#include<stdio.h>
|
||||
#include<vector>
|
||||
typedef struct{
|
||||
int to;
|
||||
int time;
|
||||
int cost;
|
||||
} path;
|
||||
using namespace std;
|
||||
int start,target;
|
||||
int best_cost=2147483647;
|
||||
int time_limit;
|
||||
int m,n;
|
||||
vector<path> graph[66000];
|
||||
bool visited[66000]={0};
|
||||
void dfs(short from,int time,int cost){
|
||||
visited[from]=true;
|
||||
for(auto i=graph[from].begin();i<graph[from].end();i++){
|
||||
if(i->to==target){
|
||||
if(time+i->time<=time_limit&&cost+i->cost<best_cost){
|
||||
best_cost=cost+i->cost;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if(time+i->time>time_limit||cost+i->cost>best_cost||visited[i->to]==true){
|
||||
continue;
|
||||
}
|
||||
dfs(i->to,time+i->time,cost+i->cost);
|
||||
}
|
||||
visited[from]=false;
|
||||
return;
|
||||
}
|
||||
int main(){
|
||||
int from,to,time,cost;
|
||||
scanf("%d%d",&n,&m);
|
||||
for(int i=0;i<m;i++){
|
||||
scanf("%d%d%d%d",&from,&to,&time,&cost);
|
||||
graph[from].push_back({to,time,cost});
|
||||
}
|
||||
scanf("%d%d%d",&start,&target,&time_limit);
|
||||
dfs(start,0,0);
|
||||
if(best_cost==2147483647){
|
||||
best_cost=-1;
|
||||
}
|
||||
printf("%d",best_cost);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue