Задача о коридоре и дверях
Помогите перевести из C++ в C#. Я не спец в C# и не понимаю почему переведенный код работает через одно место
Группа людей должна пройти по коридору, где есть пустые комнаты и двери. Когда человек проходит впервые раз в журнал записывается о#, где # номер двери, когда другой человек во второй раз проходит двери, он ее закрывает и записывается з#
Рабочий код С++
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <clocale>
#include <utility>
#define pb push_back
#define mp std::make_pair
std::string get_str(long long number) {
std::string res = "";
while (number > 0) {
res += char(number % 10 + '0');
number /= 10;
}
for (size_t i = 0; i < res.size() / 2; ++i)
std::swap(res[i], res[res.size() - i - 1]);
return res;
}
int main() {
setlocale(LC_ALL, "Russian");
std::string hallway; int N;
std::cin >> hallway >> N;
std::vector<bool> door(N, 0); int cnt = 1;
std::vector<std::pair<long long, int>> report;
long long motion = 1;
for (size_t i = 0; i < hallway.size(); ++i) {
if (hallway[i] == '|') {
int amount_door = 0;
size_t j = i;
while (j < hallway.size() && hallway[j] == '|') {
++amount_door;
++j;
}
for (size_t num = 0; num < N; ++num) {
j = 0;
long long motion_to = motion + num * (N + 1);
while (j < amount_door) {
report.pb(mp(motion_to, cnt + j));
++j;
}
}
i += amount_door;
cnt += amount_door;
}
motion += N;
}
std::sort(report.begin(), report.end(), [](const std::pair<long long, int>& a, const std::pair<long long, int>& b) {
if (a.first == b.first) return a.second < b.second;
return a.first < b.first;
});
std::string ans = "";
for (size_t i = 0; i < report.size(); ++i) {
size_t dn = report[i].second;
ans += (door[dn - 1] ? 'з' : 'о') + get_str(dn) + ' ';
door[dn - 1] = (door[dn - 1] ? 0 : 1);
std::cout << dn << '\n';
}
std::cout << ans << '\n';
return 0;
}
Входные данные:
_|_|_|__|__|_
10
Выход:
о1 о2 з1 о3 з2 о1 з3 о2 з1 о4 о3 з2 о1 з4 з3 о2 з1 о5 о4 о3 з2 о1 з5 з4 з3 о2 з1 о5 о4 о3 з2 о1 з5 з4 з3 о2 з1 о5 о4 о3 з2 з5 з4 з3 о5 о4 з5 з4 о5 з5
И это правильно
Нерабочий код C#
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
internal static class Program
{
public static void Resize<T>(this List<T> list, int newSize, T value = default(T))
{
if (list.Count > newSize)
list.RemoveRange(newSize, list.Count - newSize);
else if (list.Count < newSize)
{
for (int i = list.Count; i < newSize; i++)
{
list.Add(value);
}
}
}
public static void Swap<T>(this List<T> list1, List<T> list2)
{
List<T> temp = new List<T>(list1);
list1.Clear();
list1.AddRange(list2);
list2.Clear();
list2.AddRange(temp);
}
public static List<T> InitializedList<T>(int size, T value)
{
List<T> temp = new List<T>();
for (int count = 1; count <= size; count++)
{
temp.Add(value);
}
return temp;
}
public static List<List<T>> NestedList<T>(int outerSize, int innerSize)
{
List<List<T>> temp = new List<List<T>>();
for (int count = 1; count <= outerSize; count++)
{
temp.Add(new List<T>(innerSize));
}
return temp;
}
public static List<List<T>> NestedList<T>(int outerSize, int innerSize, T value)
{
List<List<T>> temp = new List<List<T>>();
for (int count = 1; count <= outerSize; count++)
{
temp.Add(InitializedList(innerSize, value));
}
return temp;
}
private static void Main(String[] args)
{
string hallway;
int N;
hallway = Console.ReadLine();
N = int.Parse(Console.ReadLine());
List<bool> door = InitializedList(N, false);
int cnt = 1;
List<Tuple<long, int>> report = new List<Tuple<long, int>>();
long motion = 1;
for (int i = 0; i < hallway.Length; ++i)
{
if (hallway[i] == '|')
{
int amount_door = 0;
int j = i;
while (j < hallway.Length && hallway[j] == '|')
{
++amount_door;
++j;
}
for (int num = 0; num < N; ++num)
{
j = 0;
long motion_to = motion + num * (N + 1);
while (j < amount_door)
{
report.Add(Tuple.Create(motion_to, cnt + j));
++j;
}
}
i += amount_door;
cnt += amount_door;
}
motion += N;
}
report.Sort((Tuple<long, int> a, Tuple<long, int> b) =>
{
if (a.Item1 == b.Item1)
{
if (a.Item2 < b.Item2)
{
return 1;
}
return 0;
}
if (a.Item1 < b.Item1)
{
return 1;
}
return 0;
});
string ans = "";
for (int i = 0; i < report.Count; ++i)
{
int dn = report[i].Item2;
int dan = dn;
string res = "";
while (dan > 0)
{
res += (char)(dan % 10 + '0');
dan /= 10;
}
for (int j = 0; j < res.Length / 2; ++j)
{
StringBuilder sb = new StringBuilder(res);
char temp = sb[res.Length - j - 1];
sb[res.Length - j - 1] = res[j];
sb[j] = temp;
res = sb.ToString();
}
ans += (door[dn - 1] ? 'з' : 'o') + res + ' ';
door[dn - 1] = (door[dn - 1] ? 0 : 1) != 0;
}
Console.Write(ans);
Console.Write('\n');
}
}
Входные данные:
_|_|_|__|__|_
10
Выход:
o5 o3 з3 o3 o4 з4 o4 з4 o4 з4 o4 з4 o4 з4 з5 o5 з5 o5 з5 o5 з5 o5 з3 o3 з3 o3 o1 з1 o1 з1 o1 з1 o1 з1 o1 o2 з5 з2 o2 з2 o2 з2 o2 з2 o2 з3 o3 з3 з2 з1
И это НЕ правильно
Мне кажется у меня проблемы в C# с сортировкой
Так же был сделан код на C#, но он слишком много времени занимает 25/26 Time limit exceeded. Если возможно, то его желательно улучшить. Проблема, что входные данные безграничны, но тесты сделаны, чтоб можно было проверить код за 11 секунд. Мне сказали "идеальный код за 6 секунд справляется" и мне сказали "это задача на паттерны".
using System;
using System.Collections.Generic;
internal static class Program
{
private static void Main(String[] args)
{
string hallway; int n;
hallway = Console.ReadLine();
n = Convert.ToInt32(Console.ReadLine());
List<bool> open = new List<bool>(hallway.Length);
for(int i = 0;i<hallway.Length;i++){
open.Add(false);
}
List<int> door = new List<int>();
for(int i = 0;i<hallway.Length;i++){
door.Add(-1);
}
List<int>pos = new List<int>();
for(int i = 0;i<n;i++){
pos.Add(-1);
}
int cnt = 1;
int lim = 1;
int first = 0;
string str = "";
while(first < n){
if(hallway.Length <= pos[first]){
++first;
continue;
}
for(int i = first; i < lim; ++i){
int cur_pos = pos[i] + 1;
if(cur_pos > hallway.Length) continue;
while(cur_pos < hallway.Length && (hallway[cur_pos] == '|')){
if(door[cur_pos] == -1){
door[cur_pos] = cnt;
++cnt;
}
if(open[cur_pos] == true){
str+="з" + door[cur_pos].ToString() + " ";
open[cur_pos] = false;
}
else{
str+="о" + door[cur_pos].ToString() + " ";
open[cur_pos] = true;
}
++cur_pos;
}
pos[i] = cur_pos;
}
lim = Math.Min(n,lim+1);
}
Console.WriteLine(str);
}
}
Ответы (1 шт):
Методом дедукции и телепатии написал вот такое решение.
private static void Main(string[] args)
{
string hallway = "_|_|_|__|__|_";
int n = 10;
hallway = hallway.Replace("|_", "|");
int[] doorIndexes = hallway.Select((c, i) => c == '|' ? i : -1).Where(x => x >= 0).ToArray();
bool[] doorState = new bool[doorIndexes.Length];
List<string> log = new List<string>();
for (int step = -n; step < hallway.Length; step++)
{
for (int member = n; member > 0; member--)
{
int position = step + member;
if (position >= 0 && position < hallway.Length && hallway[position] == '|')
{
int doorIndex = Array.IndexOf(doorIndexes, position);
doorState[doorIndex] = !doorState[doorIndex];
log.Add((doorState[doorIndex] ? "о" : "з") + (doorIndex + 1));
}
}
}
string result = string.Join(" ", log);
string expected = "о1 о2 з1 о3 з2 о1 з3 о2 з1 о4 о3 з2 о1 з4 з3 о2 з1 о5 о4 о3 з2 о1 з5 з4 з3 о2 з1 о5 о4 о3 з2 о1 з5 з4 з3 о2 з1 о5 о4 о3 з2 з5 з4 з3 о5 о4 з5 з4 о5 з5";
Console.WriteLine(expected);
Console.WriteLine(result);
Console.WriteLine(expected == result);
Console.ReadKey();
}
Вывод в консоль.
о1 о2 з1 о3 з2 о1 з3 о2 з1 о4 о3 з2 о1 з4 з3 о2 з1 о5 о4 о3 з2 о1 з5 з4 з3 о2 з1 о5 о4 о3 з2 о1 з5 з4 з3 о2 з1 о5 о4 о3 з2 з5 з4 з3 о5 о4 з5 з4 о5 з5
о1 о2 з1 о3 з2 о1 з3 о2 з1 о4 о3 з2 о1 з4 з3 о2 з1 о5 о4 о3 з2 о1 з5 з4 з3 о2 з1 о5 о4 о3 з2 о1 з5 з4 з3 о2 з1 о5 о4 о3 з2 з5 з4 з3 о5 о4 з5 з4 о5 з5
True
C++ и C# - очень разные языки, когда дело касается обработки данных.