Sudoku solver hangs for some games - c++

I have written an implementation of Donald Knuth's Algorithm X for solving exact cover problems and applied it to Sudoku for the purpose of solving Project Euler Problem 96. My code is a translation from Python into C++ of Ali Assaf's implementation of the same algorithm.
My version is solves most of the grids contained in this text file, but it hangs for Grid 06.
Grid 06
100920000
524010000
000000070
050008102
000000000
402700090
060000000
000030945
000071006
I have used a bunch of exploratory cout statements, but I have not been able to figure out what is causing the program to hang.
Please let me know if you need more information to be able to understand my code.
#include <algorithm>
#include <array>
#include <fstream>
#include <iostream>
#include <map>
#include <set>
#include <vector>
using namespace std;
bool solve(map<int, set<int>>* X, map<int, array<int, 4>>* Y,
vector<int>* solution);
void select_row(map<int, set<int>>* X, map<int, array<int, 4>>* Y,
vector<set<int>>* cs, int r);
void deselect_row(map<int, set<int>>* X, map<int, array<int, 4>>* Y,
vector<set<int>>* cs, int r);
// square boxes only
static const int BOX_SIZE = 3; // standard sudoku grid
static const int SIZE = BOX_SIZE*BOX_SIZE;
int main() {
int top_left_sum = 0;
// initialize the sparse matrix representation of the sudoku problem
map<int, set<int>> C; // constraints/columns
for (int i = 0; i < 4*SIZE*SIZE; i++) {
C[i] = set<int>();
}
map<int, array<int, 4>> R; // subsets/rows
for (int i = 0; i < SIZE*SIZE*SIZE; i++) {
// i is the subset index and encodes location and number on grid
int index = i/SIZE;
int row = i/(SIZE*SIZE);
int column = (i/SIZE) % SIZE;
int box = BOX_SIZE*(row/BOX_SIZE) + column/BOX_SIZE;
int value = i % SIZE;
// there are 4 constaints satisfied by each number placement
array<int, 4> subset;
// insert the keys of constraints that subset satisfies
subset[0] = (index); // row-column
subset[1] = (SIZE*SIZE + SIZE*row + value); // row-number
subset[2] = (2*SIZE*SIZE + SIZE*column + value); // column-number
subset[3] = (3*SIZE*SIZE + SIZE*box + value); // box-number
R.insert(pair<int, array<int, 4>>(i, subset));
for (auto c : subset) {
C[c].insert(i);
}
}
ifstream ifs("../sudoku.txt");
string line;
while (getline(ifs, line)) {
if (line[0] == 'G') {
map<int, set<int>> X = C;
map<int, array<int, 4>> Y = R;
vector<int> solution;
for (int i = 0; i < SIZE; i++) {
getline(ifs, line);
for (int j = 0; j < SIZE; j++) {
if (line[j] != '0') {
int r = SIZE*SIZE*i + SIZE*j + line[j] - '1';
solution.push_back(r);
vector<set<int>> cs;
select_row(&X, &Y, &cs, r);
}
}
}
solve(&X, &Y, &solution);
sort(solution.begin(), solution.end());
top_left_sum += 100*(solution[0] % SIZE + 1)
+ 10*(solution[1] % SIZE + 1)
+ solution[2] % SIZE + 1;
// display solution
for (size_t i = 0; i < solution.size(); i++) {
if (i % 9 == 0) cout << endl;
cout << solution[i] % 9 + 1 << ' ';
} cout << endl << endl;
}
}
ifs.close();
cout << top_left_sum << endl;
return 0;
}
bool solve(map<int, set<int>>* X, map<int, array<int, 4>>* Y,
vector<int>* solution) {
if ((*X).empty()) return true;
// find the column with the minimum number of nonzero elements
map<int, set<int>>::iterator c_min = (*X).begin();
for (map<int, set<int>>::iterator c = ++(*X).begin();
c != (*X).end(); ++c) {
if ((*c).second.size() < (*c_min).second.size()) {
c_min = c;
}
}
// for each row pointed to by c_min, call solve recursively
for (auto r : (*c_min).second) {
(*solution).push_back(r);
vector<set<int>> cs;
select_row(X, Y, &cs, r);
if (solve(X, Y, solution)) return true;
deselect_row(X, Y, &cs, r);
(*solution).pop_back();
}
return false;
}
void select_row(map<int, set<int>>* X, map<int, array<int, 4>>* Y,
vector<set<int>>* cs, int r) {
for (auto j : (*Y)[r]) {
for (auto i : (*X)[j]) {
for (auto k : (*Y)[i]) {
if (k != j) (*X)[k].erase(i);
}
}
(*cs).push_back((*X)[j]);
(*X).erase(j);
}
return;
}
void deselect_row(map<int, set<int>>* X, map<int, array<int, 4>>* Y,
vector<set<int>>* cs, int r) {
for (array<int, 4>::reverse_iterator j = (*Y)[r].rbegin();
j != (*Y)[r].rend(); ++j) {
(*X)[*j] = (*cs).back();
(*cs).pop_back();
for (auto i : (*X)[*j]) {
for (auto k : (*Y)[i]) {
if (k != *j) (*X)[k].insert(i);
}
}
}
return;
}

As PaulMackenzie pointed out, the problem with my code was that I was erasing objects which still had pointers to them initialized, specifically the integers inside the set (*c_min).second that I iterate over in my solve function.
I fixed this by making a copy of (*c_min).second and iterating over the copy.
The fixed version of the solve function looks like this:
bool solve(map<int, set<int>>* X, map<int, array<int, 4>>* Y,
vector<int>* solution) {
if ((*X).empty()) return true;
// find the column with the minimum number of nonzero elements
map<int, set<int>>::iterator c_min = (*X).begin();
for (map<int, set<int>>::iterator c = ++(*X).begin();
c != (*X).end(); ++c) {
if ((*c).second.size() < (*c_min).second.size()) {
c_min = c;
}
}
set<int> c = (*c_min).second; // ADDED LINE
// for each row pointed to by c_min, call solve recursively
for (auto r : c) { // CHANGED LINE
(*solution).push_back(r);
vector<set<int>> cs;
select_row(X, Y, &cs, r);
if (solve(X, Y, solution)) return true;
deselect_row(X, Y, &cs, r);
(*solution).pop_back();
}
return false;
}

Related

R-->cpp how to get C++ pointers to work with sourceCpp (Bellman Ford algorithm)

I'm trying to port a few functions over to r from cpp using rcpp directly using sourceCpp. I'm a total novice so apologies for poorly used language or post. Trying to port over the Bellman Ford algorithm (from Gupte, Shankar, Li, Muthukrishnan, Iftode).
I'm getting two errors:
cannot convert 'SEXP' to 'Rcpp::traits::input_parameter::type* {aka Rcpp::InputParameter*} in initialization
invalid user-defined conversion from 'Rcpp::traits::input_parameter::type {aka Rcpp::InputParameter}' to 'int' [-fpermissive]
Bonus confusion: Also, R studio shows line errors as outside of the range of the code (error in line 600, but Cpp code is only 500 lines long)
I'm guessing this is something to do with class types, wrapping functions, not being able to use pointers or something like that in the very first line. Please let me know how I might adjust this code to correctly export this function to r.
Thank you.
#include <Rcpp.h> // added this
using namespace Rcpp; // added
#define MAXV 100000
using namespace std; // commented this out...? don't, throws a lot of errors
struct edge {
int u, v, weight;
edge(int _u, int _v) {
u = _u, v = _v, weight = -1;
}
edge(int _u, int _v, int _weight) {
u = _u, v = _v, weight = _weight;
}
};
// general stuff
int LPvalue; // value for the dual LP
int cycleCount;
int V, E;
vector <edge> edges;
vector <edge> original_edges;
ofstream results, summary;
// stuff for labeling
vector <int> edgesDAG; // edges left over from eulerian subgraph
vector <int> edgesEulerian; // maximal eulerian subgraph
set<int> adjDAG[MAXV]; // these adjacency lists still just keep edge indices
set<int> adjEulerian[MAXV];
bool inEulerian[MAXV];
// stuff for Bellman-Ford
int dist[MAXV]; // vertex -> distance
// [[Rcpp::export]] //ERRORS
void bellman_ford(int *pred) {
for(int i = 0; i < V; i++) {
dist[i] = V;
pred[i] = -1;
}
dist[0] = 0;
int i;
for(i = 0; i < V; i++) {
bool changed = false;
//printf("%d",i);
for(int j = 0; j < E; j++) {
int u = edges[j].u;
int v = edges[j].v;
int w = edges[j].weight;
if(dist[v] > dist[u] + w) {
dist[v] = dist[u] + w;
pred[v] = j;
changed = true;
}
}
if(dist[0] < 0) {
break;
}
if(!changed) {
printf("Bellman Ford done after %d of %d iters\n", i, V);
//results << "Bellman-Ford done after " << i << " of " << V << " iters" << endl;
break;
}
}
printf("Bellman Ford took %d of %d iters\n", i+1, V);
}
use std::vector<int> instead of int *
use Rcpp::Rcout instead of std::ofstream
The following code should compile:
#include <Rcpp.h> // added this
using namespace Rcpp; // added
#define MAXV 100000
using namespace std; // commented this out...? don't, throws a lot of errors
struct edge {
int u, v, weight;
edge(int _u, int _v) {
u = _u, v = _v, weight = -1;
}
edge(int _u, int _v, int _weight) {
u = _u, v = _v, weight = _weight;
}
};
// general stuff
int LPvalue; // value for the dual LP
int cycleCount;
int V, E;
vector <edge> edges;
vector <edge> original_edges;
// stuff for labeling
vector <int> edgesDAG; // edges left over from eulerian subgraph
vector <int> edgesEulerian; // maximal eulerian subgraph
set<int> adjDAG[MAXV]; // these adjacency lists still just keep edge indices
set<int> adjEulerian[MAXV];
bool inEulerian[MAXV];
// stuff for Bellman-Ford
int dist[MAXV]; // vertex -> distance
// [[Rcpp::export]]
void bellman_ford(std::vector<int> pred) {
for(int i = 0; i < V; i++) {
dist[i] = V;
pred[i] = -1;
}
dist[0] = 0;
int i;
for(i = 0; i < V; i++) {
bool changed = false;
//printf("%d",i);
for(int j = 0; j < E; j++) {
int u = edges[j].u;
int v = edges[j].v;
int w = edges[j].weight;
if(dist[v] > dist[u] + w) {
dist[v] = dist[u] + w;
pred[v] = j;
changed = true;
}
}
if(dist[0] < 0) {
break;
}
if(!changed) {
Rcpp::Rcout << "Bellman-Ford done after " << i << " of " << V << " iters" << endl;
break;
}
}
Rcpp::Rcout << "Bellman Ford took" << i + 1 << " of " << V << " iters" << std::endl;
}

STL list iterator outside of range

I can't know why this error happened in my code.(Actually, this is my first time to use std:: list.) When I use it++ it makes error 'list iterator outside of range', and when I use ++it it makes error 'list iterator not incrementable'. Please help me!
#include<stdio.h>
#include<stdlib.h>
#include<list>
#include<stack>
using namespace std;
typedef struct tag_vpos { int data; list <int>::iterator pos; } vpos;
list<int> row[100];
stack<vpos> save[100];
int col[100][100], n, r, rowsize[100];
//int row[100][100];
long long cnt;
void arr(int x, int y) {
list<int>::iterator it = row[y].begin();
while (it != row[y].end()) {
if (!col[x][*it]) {
vpos t = { *it, it }, temp;
int val = *it;
col[x][val] = 1;
row[y].erase(it++);
save[y].push(t);
if (x == r - 1) { // if x th column is the end of right
if (y == r - 1) cnt++; // if y th column is the bottom, count this
else arr(0, y + 1);// else fill next row, first column
}
else { arr(x + 1, y); } // else fill next right square
temp = save[y].top();
row[y].insert(temp.pos, temp.data);
save[y].pop();
col[x][temp.data] = 0;
}
else it++;
}
return;
}
void main() {
printf("Input n, r (paint r x r field with n colors, same color cannot be used in same column and row) \n: ");
scanf("%d %d", &n, &r);
for (int i = 0; i < r; i++) {
for (int j = 0; j < n; j++) row[i].push_back(j);
rowsize[i] = n;
}
printf("start\n");
arr(0, 0);
printf("There are %ld ways to paint.\n", cnt);
}
To remove elements from STL container while iterating you combine the container's erase function (they all have this) with the remove or remove_if algorithm. Otherwise your invalidating your iterators underneath yourself.
void delete_elements(std::list &list)
{
list.erase(
std::remove_if(
list.begin(),
list.end(),
[](char x){return std::isspace(x);}),
list.end() );
}

Can't understand why my program throws error

My code is in
#include <iostream>
#include <string>
#include <algorithm>
#include <climits>
#include <vector>
#include <cmath>
using namespace std;
struct State {
int v;
const State *rest;
void dump() const {
if(rest) {
cout << ' ' << v;
rest->dump();
} else {
cout << endl;
}
}
State() : v(0), rest(0) {}
State(int _v, const State &_rest) : v(_v), rest(&_rest) {}
};
void ss(int *ip, int *end, int target, const State &state) {
if(target < 0) return; // assuming we don't allow any negatives
if(ip==end && target==0) {
state.dump();
return;
}
if(ip==end)
return;
{ // without the first one
ss(ip+1, end, target, state);
}
{ // with the first one
int first = *ip;
ss(ip+1, end, target-first, State(first, state));
}
}
vector<int> get_primes(int N) {
int size = floor(0.5 * (N - 3)) + 1;
vector<int> primes;
primes.push_back(2);
vector<bool> is_prime(size, true);
for(long i = 0; i < size; ++i) {
if(is_prime[i]) {
int p = (i << 1) + 3;
primes.push_back(p);
// sieving from p^2, whose index is 2i^2 + 6i + 3
for (long j = ((i * i) << 1) + 6 * i + 3; j < size; j += p) {
is_prime[j] = false;
}
}
}
}
int main() {
int N;
cin >> N;
vector<int> primes = get_primes(N);
int a[primes.size()];
for (int i = 0; i < primes.size(); ++i) {
a[i] = primes[i];
}
int * start = &a[0];
int * end = start + sizeof(a) / sizeof(a[0]);
ss(start, end, N, State());
}
It takes one input N (int), and gets the vector of all prime numbers smaller than N.
Then, it finds the number of unique sets from the vector that adds up to N.
The get_primes(N) works, but the other one doesn't.
I borrowed the other code from
How to find all matching numbers, that sums to 'N' in a given array
Please help me.. I just want the number of unique sets.
You've forgotten to return primes; at the end of your get_primes() function.
I'm guessing the problem is:
vector<int> get_primes(int N) {
// ...
return primes; // missing this line
}
As-is, you're just writing some junk here:
vector<int> primes = get_primes(N);
it's undefined behavior - which in this case manifests itself as crashing.

Variadic nested loops

I am working on a N dimensional grid.
I would like to generate nested loops depending on any dimension (2D, 3D, 4D, etc...).
How can I do that in an elegant and fast way ? Below a simple illustration of my problem.
I am writing in C++ but I think this kind of question can be useful for other languages.
I need to know the indices (i,j,k...) in my do stuff part.
Edit : lower_bound and upper_bound represents the indexes in the grid so they are always positive.
#include <vector>
int main()
{
// Dimension here is 3D
std::vector<size_t> lower_bound({4,2,1});
std::vector<size_t> upper_bound({16,47,9});
for (size_t i = lower_bound[0]; i < upper_bound[0]; i ++)
for (size_t j = lower_bound[1]; j < upper_bound[1]; j ++)
for (size_t k = lower_bound[2]; k < upper_bound[2]; k ++)
// for (size_t l = lower_bound[3]; l < upper_bound[3]; l ++)
// ...
{
// Do stuff such as
grid({i,j,k}) = 2 * i + 3 *j - 4 * k;
// where grid size is the total number of vertices
}
}
Following may help:
bool increment(
std::vector<int>& v,
const std::vector<int>& lower,
const std::vector<int>& upper)
{
assert(v.size() == lower.size());
assert(v.size() == upper.size());
for (auto i = v.size(); i-- != 0; ) {
++v[i];
if (v[i] != upper[i]) {
return true;
}
v[i] = lower[i];
}
return false;
}
And use it that way:
int main() {
const std::vector<int> lower_bound({4,2,1});
const std::vector<int> upper_bound({6,7,4});
std::vector<int> current = lower_bound;
do {
std::copy(current.begin(), current.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
} while (increment(current, lower_bound, upper_bound));
}
Live demo
An iterative approach could look like this:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> lower_bound({-4, -5, -6});
std::vector<int> upper_bound({ 6, 7, 4});
auto increase_counters = [&](std::vector<int> &c) {
for(std::size_t i = 0; i < c.size(); ++i) {
// This bit could be made to look prettier if the indices are counted the
// other way around. Not that it really matters.
int &ctr = c .rbegin()[i];
int top = upper_bound.rbegin()[i];
int bottom = lower_bound.rbegin()[i];
// count up the innermost counter
if(ctr + 1 < top) {
++ctr;
return;
}
// if it flows over the upper bound, wrap around and continue with
// the next.
ctr = bottom;
}
// end condition. If we end up here, loop's over.
c = upper_bound;
};
for(std::vector<int> counters = lower_bound; counters != upper_bound; increase_counters(counters)) {
for(int i : counters) {
std::cout << i << ", ";
}
std::cout << "\n";
}
}
...although whether this or a recursive approach is more elegant rather depends on the use case.
#include <iostream>
#include <vector>
template <typename Func>
void process(const std::vector<int>& lower, const std::vector<int>& upper, Func f)
{
std::vector<int> temp;
process(lower, upper, f, 0, temp);
}
template <typename Func>
void process(const std::vector<int>& lower, const std::vector<int>& upper, Func f,
int index, std::vector<int>& current)
{
if (index == lower.size())
{
f(current);
return;
}
for (int i = lower[index]; i < upper[index]; ++i)
{
current.push_back(i);
process(lower, upper, f, index + 1, current);
current.pop_back();
}
}
int main()
{
// Dimension here is 3D
std::vector<int> lower_bound({-4, -5, 6});
std::vector<int> upper_bound({6, 7, 4});
// Replace the lambda below with whatever code you want to process
// the resulting permutations.
process(lower_bound, upper_bound, [](const std::vector<int>& values)
{
for (std::vector<int>::const_iterator it = values.begin(); it != values.end(); ++it)
{
std::cout << *it << " ";
}
std::cout << std::endl;
});
}
Probably some typos an whatnot, but I'd flatten the whole range.
This is based on the idea that the range can be described as
x_0 + d_0*(x_1+d_1*(x_2+d_2....)
So we can roll our own that way
std::vector<int> lower_bound{-4,-5,6};
std::vector<int> upper_bound{6,7,4};
//ranges
std::vector<int> ranges;
for (size_t i = 0; i < lower_bound.size(); i++) {
ranges.push_back(upper_bound[i]-lower_bound[i]);
}
for (int idx = 0; idx < numel; idx++) {
//if you don't need the actual indicies, you're done
//extract indexes
int idx2 = idx;
std::vector<int> indexes;
for (int i = 0; i < ranges.size(); i++) {
indexes.push_back(idx2%ranges[i]-lower_bound[i]);
idx2 = idx2/ranges[i];
}
//do stuff
grid[idx] = 2 * indexes[0] + 3 *indexes[1] - 4 * indexes[2];
}
Edit: to be more generic:
template <typename D>
void multi_for(const std::vector<int>& lower_bound, const std::vector<int> upper_bound, D d) {
std::vector<int> ranges;
for (size_t i = 0; i < lower_bound.size(); i++) {
ranges.push_back(upper_bound[i]-lower_bound[i]);
}
size_t numel = std::accumulate(ranges.begin(), ranges.end(), std::multiplies<int,int>{});
for (int idx = 0; idx < numel; idx++) {
//if you don't need the actual indicies, you're done
//extract indexes
int idx2 = idx;
std::vector<int> indexes;
for (int i = 0; i < ranges.size(); i++) {
indexes.push_back(idx2%ranges[i]-lower_bound[i]);
idx2 = idx2/ranges[i];
}
//do stuff
d(idx,indexes);
}
}
//main
size_t* grid;//initialize to whateer
std::vector<int> lower_bound{-4,-5,6};
std::vector<int> upper_bound{6,7,4};
auto do_stuff = [grid](size_t idx, const std::vector<int> indexes) {
grid[idx] = 2 * indexes[0] + 3 *indexes[1] - 4 * indexes[2];
};
multi_for(lower_bound,upper_bound,do_stuff);
A recursive function may help you achieve what you want.
void Recursive( int comp )
{
if(comp == dimension)
{
// Do stuff
}
else
{
for (int e = lower_bound[comp]; e < upper_bound[comp]; e++)
Recursive(comp+1);
}
}
Some additions may be necessary in the function signature if you need to know the current indices (i,j,k,...) in your "Do Stuff" section.
This is a clean way to have access to these indices
void Recursive( int comp, int dimension )
{
static std::vector<int> indices;
if( comp == 0 ) // initialize indices
{
indices.clear();
indices.resize(dimension, 0);
}
if(comp == dimension -1)
{
// Do stuff
}
else
{
int& e = indices[comp];
for (e = lower_bound[comp]; e < upper_bound[comp]; e++)
Recursive(comp+1);
}
}
This is however not usable along multiple threads, due to the shared static vector.

Querying for a value that's bigger than X, while having another condition

I have list of pair [x;y] where x is unique and y can be duplicate(integers).
Here lies a problem:
Given a pair [x;y], find new pair [k;m], such that:
k > x
m >= y
k - x is minimized.
Now, I've solved this problem with this logic; I sort pairs by x, and then start naive O(n^2) algorithm on it. It seems to work fine, except it's too slow.
Can I do better?
The actual problem im trying to solve, is here: http://www.spoj.com/problems/VBOSS/
and my current code:
#include <stdio.h>
#include <utility>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
struct employee
{
int id;
int salary;
int height;
int parent_index;
int sub_ordinates;
int cur;
bool important;
bool operator < (const employee& e) const
{
if(height == e.height)
return salary > e.salary;
return (height > e.height);
}
};
// problem states explictly that no two employees
// have same salary.
struct salary_predicate
{
inline bool operator() (const employee& struct1, const employee& struct2)
{
return (struct1.salary > struct2.salary);
}
};
const int MAX_EMPLOYEES = 30000;
const int MAX_QUERIES = 200;
employee employees[MAX_EMPLOYEES];
int queries[MAX_QUERIES];
int main()
{
int test_cases;
scanf("%d", &test_cases);
while(test_cases--)
{
int employeeCount, queryCount;
scanf("%d %d", &employeeCount, &queryCount);
int i = 0;
int j = 0;
while(i < employeeCount)
{
employees[i].parent_index = -1;
employees[i].sub_ordinates = 0;
employees[i].cur = i;
employees[i].important = false;
scanf("%d %d %d", &employees[i].id, &employees[i].salary, &employees[i].height);
i++;
}
map<int, int> mapper;
while(j < queryCount)
{
scanf("%d", &queries[j]);
mapper.insert(pair<int, int>(queries[j], -1));
j++;
}
// now step1; sort employees structure
// based on SALARY!!
sort(employees, employees + employeeCount, salary_predicate());
for(int k = 0; k < employeeCount; k++)
{
employees[k].cur = k;
if(mapper.find(employees[k].id) != mapper.end())
{
mapper[employees[k].id] = k;
employees[k].important = true;
}
}
int found = 0;
for(int l = employeeCount - 1; l >= 0; l--)
{
int gef = l - 1;
// check out information about previous worker,
// he might give us some valuable information!
// with his help, we know if we can skip some shit :)
if(l + 1 < employeeCount && employees[l + 1].parent_index != -1)
{
// if previous employee is smaller than our current employee
// then we can skip some people, becase we know that answer cant be
// smalle than that :)
if(employees[l + 1].height <= employees[l].height)
gef = employees[l + 1].parent_index - 1;
}
// find boss!
for(int b = gef; b >= 0; b--)
{
if(employees[b].height >= employees[l].height)
{
employees[l].parent_index = b;
employees[b].sub_ordinates += employees[l].sub_ordinates + 1;
break;
}
}
// this bit makes sure if we have processed all necessay things,
// then we can basically stop our work.
if(employees[l].important) found++;
if(found == mapper.size()) break;
}
// time to print it out.
for(int b = 0; b < queryCount; b++)
{
int id = queries[b];
int index = mapper[id];
int parent_index = employees[index].parent_index;
int parent = parent_index < 0 ? 0 : employees[parent_index].id;
printf("%d %d\r\n", parent, employees[index].sub_ordinates);
}
}
return 0;
}
salary=x, and height=y.
I would start by eliminating all records where m<y or k<=x. Then find the item with the smallest k value out of what's left. Both of these should be linear, so your overall complexity should also be linear.
struct p {
int k, m;
};
p find_item(p xy, std::vector<p> &values) {
auto end = std::partition(values.begin(), values.end(),
[xy](p const &v) { return xy.k < v.k || xy.m >= v.m; });
return *std::min_element(values.begin(), end,
[](p const &a, p const &b) { return a.k < b.k; });
}