Skip to content

Commit c751883

Browse files
committed
Add montresor task got: 68/100 WIP
approximation heuristic greedy np-complete grid coloring
1 parent bc2ce37 commit c751883

File tree

3 files changed

+275
-0
lines changed

3 files changed

+275
-0
lines changed

more/montresor/got/got.cpp

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
#pragma GCC optimize ("O3")
2+
#include <bits/stdc++.h>
3+
#include "got.h"
4+
using namespace std;
5+
6+
ifstream in{"input.txt"};
7+
ofstream out{"output.txt"};
8+
#ifdef DEBUG
9+
template<class A,class B>ostream&operator<<(ostream&o,const pair<A,B>&p){cout<<"("<<p.first<<", "<<p.second<<")";return o;}
10+
template<class T,typename=typename enable_if<!is_same<T, string>::value,decltype(*begin(declval<T>()))>::type>ostream&operator<<(ostream&o,const T&v){cout<<"[";for(auto it=v.begin();it!=v.end();++it){if(it!=v.begin()){cout<<", ";}cout<<*it;}cout<<"]";return o;}
11+
void deb(){cout<<"\n";}template<class T,class...Ts>void deb(const T&t,const Ts&...args){cout<<t;if(sizeof...(args)!=0){cout<<" ";}deb(args...);}
12+
#else
13+
#define deb(...)
14+
#endif
15+
#define cout Do not use cout!!!
16+
#define cin Do not use cin!!!
17+
18+
int R,C;
19+
vector<int> grid;
20+
21+
struct UFDS {
22+
uint16_t par;
23+
uint16_t remaining = numeric_limits<uint16_t>::max();
24+
25+
bool hasWantedSize(){
26+
return remaining==0;
27+
}
28+
29+
bool isUsed(int i){
30+
return par!=i || remaining!=numeric_limits<uint16_t>::max();
31+
}
32+
};
33+
static_assert(sizeof(UFDS) == 4);
34+
35+
struct Sol {
36+
vector<UFDS> mem;
37+
int satisfied=0;
38+
39+
Sol() : mem(R*C) {
40+
for(int i=0;i<R*C;++i){
41+
mem[i].par=i;
42+
}
43+
}
44+
45+
int root(int i) {
46+
if(mem[i].par==i) return i;
47+
return mem[i].par = root(mem[i].par);
48+
}
49+
50+
void merge(int i, int j) {
51+
int ri=root(i);
52+
int rj=root(j);
53+
if (ri==rj) {
54+
return;
55+
}
56+
57+
// if(mem[rj].remaining>mem[ri].remaining){
58+
// swap(ri,rj);
59+
// }
60+
// //now ri has the highest size
61+
62+
mem[ri].remaining-=(grid[rj]-mem[rj].remaining);
63+
if (mem[ri].hasWantedSize()) {
64+
satisfied+=grid[ri];
65+
}
66+
mem[rj].par=ri;
67+
}
68+
69+
void print() {
70+
for(int i=0;i<R*C;++i){
71+
if (i!=0) {
72+
if (i%C==0){
73+
out<<"\n";
74+
} else {
75+
out<<" ";
76+
}
77+
}
78+
int ri = root(i);
79+
if (mem[ri].hasWantedSize()) {
80+
out<<grid[ri];
81+
} else {
82+
out<<0;
83+
}
84+
}
85+
out<<"\n***"<<endl;
86+
}
87+
#ifdef DEBUG
88+
void debprint() {
89+
for(int i=0;i<R*C;++i){
90+
if (i!=0) {
91+
if (i%C==0){
92+
cerr<<"\n";
93+
} else {
94+
cerr<<" ";
95+
}
96+
}
97+
int ri = root(i);
98+
99+
if(mem[ri].remaining==numeric_limits<uint16_t>::max()){
100+
cerr<<"(_,_)";
101+
} else {
102+
cerr<<"("<<grid[ri]<<","<<mem[ri].remaining<<")";
103+
}
104+
}
105+
cerr<<"\n***"<<endl;
106+
}
107+
#else
108+
inline void debprint() {}
109+
#endif
110+
};
111+
112+
vector<int> neighbors(int i) {
113+
vector<int> res;
114+
if (i%C != 0) {
115+
res.push_back(i-1);
116+
}
117+
if (i%C != C-1) {
118+
res.push_back(i+1);
119+
}
120+
if (i/C != 0) {
121+
res.push_back(i-C);
122+
}
123+
if (i/C != R-1) {
124+
res.push_back(i+C);
125+
}
126+
return res;
127+
}
128+
129+
signed main() {
130+
in>>R>>C;
131+
grid.resize(R*C);
132+
for(int i=0;i<R*C;++i){
133+
in>>grid[i];
134+
}
135+
136+
Sol allOnes;
137+
for(int i=0;i<R*C;++i){
138+
if(grid[i]==1){
139+
for(auto neigh:neighbors(i)){
140+
if(allOnes.mem[neigh].remaining==0) goto skip;
141+
}
142+
allOnes.mem[i].remaining=0;
143+
skip:;
144+
}
145+
}
146+
147+
vector<Sol> sols(min(4*1024*1024/R/C/sizeof(UFDS), (unsigned long)1000), allOnes);
148+
//sols.resize(1);
149+
int bestSatisfied=0;
150+
while(true){
151+
int s=rand()%(sols.size());
152+
Sol& sol=sols[s];
153+
154+
int i=rand()%(R*C);
155+
if(sol.mem[i].isUsed(i)) {
156+
continue;
157+
}
158+
159+
set<int> seenr;
160+
map<int,int> sizes;
161+
for(auto neigh:neighbors(i)) {
162+
if (sol.mem[neigh].isUsed(neigh)){
163+
int nr = sol.root(neigh);
164+
if (seenr.count(nr)) {
165+
continue;
166+
}
167+
seenr.insert(nr);
168+
sizes[grid[nr]] += grid[nr] - sol.mem[nr].remaining;
169+
}
170+
}
171+
172+
int bestWantedSize;
173+
if (grid[i] == 0) {
174+
// adding an empty cell
175+
int bestDiff=numeric_limits<int>::max();
176+
for(const auto& v:sizes){
177+
if (v.second < v.first && v.first-v.second<bestDiff){
178+
bestDiff=v.first-v.second;
179+
bestWantedSize=v.first;
180+
}
181+
}
182+
if (bestDiff==numeric_limits<int>::max()) {
183+
continue;
184+
}
185+
} else {
186+
// adding a cell with a castle
187+
if(sizes[grid[i]] >= grid[i]) {
188+
continue;
189+
}
190+
bestWantedSize=grid[i];
191+
sol.mem[i].remaining=grid[i]-1;
192+
}
193+
194+
for(auto neigh:neighbors(i)) {
195+
if (sol.mem[neigh].isUsed(neigh)){
196+
int nr = sol.root(neigh);
197+
if(grid[nr]==bestWantedSize){
198+
sol.merge(neigh,i);
199+
}
200+
}
201+
}
202+
203+
//sol.debprint();
204+
if (sol.satisfied > bestSatisfied) {
205+
sol.print();
206+
bestSatisfied = sol.satisfied;
207+
}
208+
}
209+
210+
return 0;
211+
}

more/montresor/got/got.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef GOT_H
2+
#define GOT_H
3+
4+
#ifdef __cplusplus
5+
// C++ code
6+
using namespace std;
7+
8+
namespace helpers {
9+
long long get_elapsed_time(void);
10+
bool has_reached_timeout(void);
11+
12+
void setup(void);
13+
}
14+
15+
#ifndef GRADER_CPP
16+
17+
__attribute__((weak))
18+
int __real_main();
19+
20+
int main() {
21+
helpers::setup();
22+
return __real_main();
23+
}
24+
25+
#define main __real_main
26+
27+
#endif
28+
29+
#else
30+
// C code
31+
#include <stdbool.h>
32+
33+
long long get_elapsed_time(void);
34+
bool has_reached_timeout(void);
35+
36+
void setup(void);
37+
38+
#error "Only C++ is supported"
39+
#endif
40+
41+
#endif
42+
#pragma once

more/montresor/got/grader.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifndef GRADER_C
2+
#define GRADER_C
3+
4+
#include "got.h"
5+
#include <errno.h>
6+
7+
8+
void setup(void) {
9+
return;
10+
}
11+
12+
13+
long long get_elapsed_time(void) {
14+
return(ENOSYS);
15+
}
16+
17+
18+
bool has_reached_timeout(void) {
19+
return(ENOSYS);
20+
}
21+
22+
#endif

0 commit comments

Comments
 (0)