Advertisement
cbotx

Kyouen Solver

Dec 14th, 2024
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.50 KB | Source Code | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Threading.Tasks;
  5. using System.Diagnostics;
  6. class CustomData
  7. {
  8.     public int id;
  9.     public List<int> p_list;
  10.     public int[] counter;
  11.     public int idx;
  12. }
  13. class Program
  14. {
  15.     static List<Tuple<int, int, List<int>>> points = new();
  16.     static int N = 6;
  17.     static List<List<int>> circles_l = new();
  18.     static bool IsConcyclicInOrder(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
  19.     {
  20.         // AC * BD = AB * CD + BC * AD
  21.         double AC = Math.Sqrt(Math.Pow(x3 - x1, 2) + Math.Pow(y3 - y1, 2));
  22.         double BD = Math.Sqrt(Math.Pow(x4 - x2, 2) + Math.Pow(y4 - y2, 2));
  23.         double AB = Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
  24.         double CD = Math.Sqrt(Math.Pow(x4 - x3, 2) + Math.Pow(y4 - y3, 2));
  25.         double BC = Math.Sqrt(Math.Pow(x3 - x2, 2) + Math.Pow(y3 - y2, 2));
  26.         double AD = Math.Sqrt(Math.Pow(x4 - x1, 2) + Math.Pow(y4 - y1, 2));
  27.         double delta = AC * BD - AB * CD - BC * AD;
  28.         return delta >= -1e-10 && delta <= 1e-10;
  29.     }
  30.  
  31.     static bool IsConcyclic(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
  32.     {
  33.         return IsConcyclicInOrder(x1, y1, x2, y2, x3, y3, x4, y4) || IsConcyclicInOrder(x1, y1, x2, y2, x4, y4, x3, y3);
  34.     }
  35.  
  36.     static void PreProcessCircles()
  37.     {
  38.  
  39.         for (int i = 0; i < N; i++)
  40.         {
  41.             for (int j = 0; j < N; j++)
  42.             {
  43.                 points.Add(new Tuple<int, int, List<int>>(j, i, new List<int>()));
  44.             }
  45.         }
  46.  
  47.         HashSet<BitArray> circles = new();
  48.         for (int i = 0; i < points.Count; i++)
  49.         {
  50.             for (int j = i + 1; j < points.Count; j++)
  51.             {
  52.                 for (int k = j + 1; k < points.Count; k++)
  53.                 {
  54.                     List<int> circle = new List<int> { i, j, k };
  55.                     for (int u = 0; u < points.Count; u++)
  56.                     {
  57.                         if (u == i || u == j || u == k)
  58.                         {
  59.                             continue;
  60.                         }
  61.                         int[] _tmp = { i, j, k, u };
  62.                         Array.Sort(_tmp);
  63.                         if (IsConcyclic(points[_tmp[0]].Item1, points[_tmp[0]].Item2, points[_tmp[1]].Item1, points[_tmp[1]].Item2, points[_tmp[2]].Item1, points[_tmp[2]].Item2, points[_tmp[3]].Item1, points[_tmp[3]].Item2))
  64.                         {
  65.                             circle.Add(u);
  66.                         }
  67.                     }
  68.                     if (circle.Count >= 4)
  69.                     {
  70.                         BitArray _bits = new(N * N, false);
  71.                         foreach (var p in circle)
  72.                         {
  73.                             _bits[p] = true;
  74.                         }
  75.                         if (!circles.Contains(_bits))
  76.                         {
  77.                             circles.Add(_bits);
  78.                             circles_l.Add(circle);
  79.                             foreach (var u in circle)
  80.                             {
  81.                                 points[u].Item3.Add(circles_l.Count - 1);
  82.                             }
  83.                         }
  84.                     }
  85.                 }
  86.             }
  87.         }
  88.     }
  89.     static List<int> Compute(int task_id, List<int> p_list, int[] counter, int idx)
  90.     {
  91.         int max_count = 0;
  92.         List<int> max_p_list = new();
  93.         int search_count = 0;
  94.  
  95.         void Dfs(int[] counter, int[] p_marked, int total_marked, int idx)
  96.         {
  97.             search_count++;
  98.             if (search_count % 1000000 == 0)
  99.             {
  100.                 Console.WriteLine($"[{task_id}][Step {search_count}]: [{string.Join(", ", p_list)}]");
  101.             }
  102.             int i_max = Math.Min(2 * N + idx, points.Count);
  103.             for (int i = idx; i < i_max; i++)
  104.             {
  105.                 if (p_marked[i] == 0)
  106.                 {
  107.                     int new_total_marked = total_marked;
  108.                     foreach (var j in points[i].Item3)
  109.                     {
  110.                         counter[j]++;
  111.                         if (counter[j] == 3)
  112.                         {
  113.                             foreach (var p in circles_l[j])
  114.                             {
  115.                                 if (p_marked[p] == 0)
  116.                                 {
  117.                                     new_total_marked++;
  118.                                 }
  119.                                 p_marked[p]++;
  120.                             }
  121.                         }
  122.                     }
  123.                     if (N * N - new_total_marked + p_list.Count + 1 > max_count)
  124.                     {
  125.                         p_list.Add(i);
  126.                         Dfs(counter, p_marked, new_total_marked, i + 1);
  127.                         p_list.RemoveAt(p_list.Count - 1);
  128.                     }
  129.  
  130.                     foreach (var j in points[i].Item3)
  131.                     {
  132.                         if (counter[j] == 3)
  133.                         {
  134.                             foreach (var p in circles_l[j])
  135.                             {
  136.                                 p_marked[p]--;
  137.                             }
  138.                         }
  139.                         counter[j]--;
  140.                     }
  141.                 }
  142.             }
  143.             if (max_count < p_list.Count)
  144.             {
  145.                 max_count = p_list.Count;
  146.                 max_p_list = new List<int>(p_list);
  147.                 Console.WriteLine($"[{task_id}]: {max_count} [{string.Join(", ", max_p_list)}]");
  148.             }
  149.         }
  150.  
  151.         Dfs(counter, new int[points.Count], 0, idx);
  152.         return max_p_list;
  153.     }
  154.  
  155.     static void AlgorithmStart()
  156.     {
  157.         List<Task<List<int>>> tasks = new();
  158.         List<int> p_list = new List<int>();
  159.         int max_count = 0;
  160.         List<int> max_p_list = null;
  161.  
  162.         void Dfs_2step(int[] counter, int idx)
  163.         {
  164.             int i_max = Math.Min(2 * N + idx, points.Count);
  165.             if (p_list.Count == 0)
  166.             {
  167.                 i_max = (N - 1) / 2;
  168.             }
  169.             for (int i = idx; i <= i_max; i++)
  170.             {
  171.                 foreach (var j in points[i].Item3)
  172.                 {
  173.                     counter[j]++;
  174.                 }
  175.                 p_list.Add(i);
  176.                 if (p_list.Count >= 2)
  177.                 {
  178.                     Console.WriteLine($"Starting task [{string.Join(",", p_list.ToArray())}]");
  179.                     var task = Task<List<int>>.Factory.StartNew(
  180.                         (Object obj) =>
  181.                         {
  182.                             CustomData data = obj as CustomData;
  183.                             if (data == null) return null;
  184.                             return Compute(data.id, data.p_list, data.counter, data.idx);
  185.                         },
  186.                         new CustomData()
  187.                         {
  188.                             id = tasks.Count,
  189.                             p_list = new List<int>(p_list),
  190.                             counter = (int[])counter.Clone(),
  191.                             idx = i + 1
  192.                         }
  193.                     );
  194.                     tasks.Add(task);
  195.                 }
  196.                 else
  197.                 {
  198.                     Dfs_2step(counter, i + 1);
  199.                 }
  200.                 p_list.RemoveAt(p_list.Count - 1);
  201.                 foreach (var j in points[i].Item3)
  202.                 {
  203.                     counter[j]--;
  204.                 }
  205.             }
  206.         }
  207.  
  208.         Dfs_2step(new int[circles_l.Count], 0);
  209.         Task.WaitAll(tasks.ToArray());
  210.         foreach (Task<List<int>> task in tasks)
  211.         {
  212.             if (max_count < task.Result.Count)
  213.             {
  214.                 max_count = task.Result.Count;
  215.                 max_p_list = task.Result;
  216.             }
  217.         }
  218.         Console.WriteLine("=========================");
  219.         Console.WriteLine($"[{N}x{N}] Final Result: {max_count} [{string.Join(", ", max_p_list)}]");
  220.     }
  221.  
  222.     static void Main()
  223.     {
  224.         PreProcessCircles();
  225.         Stopwatch stopWatch = new Stopwatch();
  226.         stopWatch.Start();
  227.         AlgorithmStart();
  228.         stopWatch.Stop();
  229.         TimeSpan ts = stopWatch.Elapsed;
  230.         string elapsedTime = string.Format("{0:00}:{1:00}:{2:00}.{3:00}",
  231.             ts.Hours, ts.Minutes, ts.Seconds,
  232.             ts.Milliseconds / 10);
  233.         Console.WriteLine("RunTime " + elapsedTime);
  234.     }
  235. }
  236.  
  237.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement