消息传递口(csp 201903-4)
原题链接
题目类型:模拟题
思路一:循环给每次一个线程一个操作机会,本以为是线性复杂度,但是因为很有可能每一次循环都仅仅只有一个线程进行了操作,因此最终导致超时。
但是这份40分的代码来之不易
总结一下debug的经验:
#include<iostream>
#include<vector>
#include<set>
#include<string.h>
using namespace std;
#define QMAX 40000
#define NMAX 10010
char Q[QMAX];
vector<pair<int, int> > I[NMAX];
int pos[NMAX];
set<int > finish;
int T, n;
char map[NMAX][NMAX]; //会存在爆内存的情况,改为char
char map2[NMAX][NMAX]; //会存在爆内存的情况,改为char
int key = 1;//key的设置存在问题
int handle(int x, int y) {
if (y > I[x].size() - 1) {
finish.erase(x);
return 0;
}
if (I[x][y].first == 1) {
//s是只有等到接受了才能向下执行
//代表是否发送
if (map2[I[x][y].second][x]) {
map2[I[x][y].second][x] = 0;
return 1;
}
if (!map[x][I[x][y].second]) {
map[x][I[x][y].second] = 1; //注意这里一定要等对面接收了才能继续!!!
key = 1;
return 0; //发送了的话仍需等等
}
else return 0;
}
else {
if (map[I[x][y].second][x] == 0) return 0; //这边不能搞反了
else {
map[I[x][y].second][x] = 0;
map2[x][I[x][y].second] = 1;
return 1;
}
}
}
int main() {
cin >> T >> n;
getchar();//第一行的换行需要读掉
while (T--) {
memset(pos, 0, sizeof(pos));
memset(map, 0, sizeof(map));
memset(map2, 0, sizeof(map2));
finish.clear();
for (int i = 0; i < n; i++) {
I[i].clear();//注意指令也需要初始化,较好的策略是使用一个队列
finish.insert(i);
//getchar();//读取换行 fgets已经读取了换行因此这里不需要了
fgets(Q, QMAX, stdin);
for (int j = 0; j<strlen(Q)-1; j+=3) { //最后一个是不包括空格的因此最后j会溢出
if (Q[j] == 'R') I[i].push_back(make_pair(0, Q[j + 1] - '0'));
else I[i].push_back(make_pair(1, Q[j + 1] - '0'));
}
}
key = 1;
while (1 && key) {
key = 0;
for (int i = 0; i < n; i++) {
if (finish.count(i) && handle(i, pos[i])) { //连续的两个S是不能一起发的 ,所以while改为if
pos[i]++;
key = 1;
}
}
}
if (finish.size() == 0) cout << "0" << endl;
else cout << "1" << endl;
/*for (int i = 0; i < n; i++) {
cout << pos[i] << endl;
}*/
}
}
思路二:使用DFS遍历,当一个线程等待时,就去调用等待完成的下一个线程来执行
日后补上DFS的代码
317号子任务(csp 201903-4)
原题链接
段错误找不出为什么
思路:如果从每个点出发去找所有的最短距离,使用floyed算法可能会超时,因此采用逆向的思维,由于有根据地的点较少,因此可以每次都调用spfa来求解最短路,需要注意的是,在m条边,n个点的情况下,spfa的复杂度为O(mn),而dijkstra的复杂度为O(n2)。因此本题采用spfa比较合适。
#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
#define NMAX 10010
#define INF 0x3f3f3f3f
int n, m, k;
vector<int> G[NMAX]; //第一个数字代表是不是行星发动机据点
vector<int> D[NMAX];
struct edge {
int form, to, length;
};
vector<edge> E;
int spfa(int s) {
stack<int > Q;
int dist[NMAX];
char inq[NMAX];
for (int i = 1; i <= n; i++) {
dist[i] = INF, inq[i] = 0;
}
Q.push(s);
inq[s] = 1;
dist[s] = 0;
while (!Q.empty()) {
int cur = Q.top();
Q.pop();
inq[cur] = 0;
for (int i = 1; i < G[cur].size(); i++) {
int en = G[cur][i];
int cur2 = E[en].to;
if (dist[cur2] > dist[cur] + E[en].length) {
dist[cur2] = dist[cur] + E[en].length;
if (!inq[cur2]) {
Q.push(cur2);
inq[cur2] = 1;
}
}
}
}
for (int i = 1; i <= n; i++) {
if (dist[i] != INF) D[i].push_back(dist[i]);
}
}
int main() {
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) {
int cur;
cin >> cur;
G[i].push_back(cur);
}
for (int i = 0; i < m; i++) {
int f, t, c;
cin >> f >> t >> c;
edge e;
e.form = f, e.to = t, e.length = c;
E.push_back(e);
G[f].push_back(E.size() - 1);
e.form = t, e.to = f, e.length = c;
E.push_back(e);
G[t].push_back(E.size() - 1); //这里图建错了
}
//进行检查
/*for (int i = 0; i < E.size(); i++) {
cout << E[i].form << " " << E[i].to << " " << E[i].length << endl;
}*/
for (int i = 1; i <= n; i++) {
if (G[i][0]) spfa(i);
}
for (int i = 1; i <= n; i++) {
sort(D[i].begin(),D[i].end());
long long res = 0;
for (int j = 0; j < k && j < D[i].size(); j++) {
res += D[i][j];
}
cout << res << endl;
}
}
The Pilots Brothers’ refrigerator(poj 2965)
原题链接
题目类型:枚举
#include<iostream>
using namespace std;
int min_num=0x3f3f3f3f, min_matrix[4][4];
int init[4][4];
int modify[4][4];
int cur[4][4];
int cons[16][4] = {
0,0,0,0,
0,0,0,1,
0,0,1,0,
0,1,0,0,
1,0,0,0,
0,0,1,1,
0,1,0,1,
1,0,0,1,
0,1,1,0,
1,0,1,0,
1,1,0,0,
0,1,1,1,
1,1,1,0,
1,0,1,1,
1,1,0,1,
1,1,1,1
};
int change[16] = { 0,1,1,1,1,2,2,2,2,2,2,3,3,3,3,4 };
int changes = 0;
void init_modify() {
memset(modify, 0, sizeof(modify));
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (cur[i][j]) {
for (int k = 0; k < 4; k++) modify[i][k]++, modify[k][j]++;
modify[i][j]++;
}
}
}
}
int ca() {
for(int x=0;x<4;x++){
for (int y = 0; y < 4; y++) {
if ((init[x][y] + modify[x][y]) % 2) return 0;
}
}
return 1;
}
int main() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
char cur;
cur = getchar();
if (cur == '-') init[i][j] = 0;
else init[i][j] = 1;
}
getchar();
}
for (int num1 = 0; num1 < 16; num1++) {
memcpy(cur[0], cons[num1], sizeof(cur[0]));
changes += change[num1];
for (int num2 = 0; num2 < 16; num2++) {
memcpy(cur[1], cons[num2], sizeof(cur[1]));
changes += change[num2];
for (int num3 = 0; num3 < 16; num3++) {
memcpy(cur[2], cons[num3], sizeof(cur[2]));
changes += change[num3];
for (int num4 = 0; num4 < 16; num4++) {
memcpy(cur[3], cons[num4], sizeof(cur[3]));
changes += change[num4];
if (changes >= min_num) goto back;
/*if (changes == 6) {
cout << "hi" << endl;
}*/
init_modify();
if (ca()) {
memcpy(min_matrix, cur, sizeof(cur));
min_num = changes;
}
back:
changes -= change[num4];
}
changes -= change[num3];
}
changes -= change[num2];
}
changes -= change[num1];
}
cout << min_num << endl;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (min_matrix[i][j] % 2) cout << i + 1 << " " << j + 1 << endl;
}
}
}
总结
今天的练习发现了很多的问题,每一道题都不是很顺。
1.题意理解不清就动手,比如第2、3题。
2.调试过程耗时,比如第三题。
3.思路不够简化导致超时等