Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.IO;
- class Solution
- {
- static bool match(Dictionary<char, int> a, Dictionary<char, int> b, char c)
- {
- if (!a.ContainsKey(c))
- return false;
- else
- {
- if (a[c] - 1 < b[c])
- return true;
- else return false;
- }
- }
- static void Main(String[] args)
- {
- int n = int.Parse(Console.ReadLine());
- string gene = Console.ReadLine();
- Dictionary<char, int> dic = new Dictionary<char, int>();
- dic.Add('A', 0);
- dic.Add('T', 0);
- dic.Add('G', 0);
- dic.Add('C', 0);
- //counting A, C, T, G
- for (int i = 0; i < n; i++)
- {
- dic[gene[i]]++;
- }
- //determining how much do we need to change
- int[] arr = new int[4];
- arr[0] = dic['A'] - n / 4;
- arr[1] = dic['T'] - n / 4;
- arr[2] = dic['G'] - n / 4;
- arr[3] = dic['C'] - n / 4;
- //for fisrt substring search
- Dictionary<char, int> needToFind = new Dictionary<char, int>();
- //for later comparsion
- Dictionary<char, int> needToFind_perma = new Dictionary<char, int>();
- //currenty how much searched letters is the substring
- Dictionary<char, int> currenlyHolds = new Dictionary<char, int>();
- //if arr[i] > 0, we need too change at least arr[i] letters
- if (arr[0] > 0)
- {
- needToFind.Add('A', arr[0]);
- currenlyHolds.Add('A', 0);
- }
- if (arr[1] > 0)
- {
- currenlyHolds.Add('T', 0);
- needToFind.Add('T', arr[1]);
- }
- if (arr[2] > 0)
- {
- currenlyHolds.Add('G', 0);
- needToFind.Add('G', arr[2]);
- }
- if (arr[3] > 0)
- {
- currenlyHolds.Add('C', 0);
- needToFind.Add('C', arr[3]);
- }
- //saving for later comparsion
- foreach (KeyValuePair<char, int> a in needToFind)
- {
- needToFind_perma.Add(a.Key, a.Value);
- }
- int min = 0;
- //determining the minimum number of letters we need to change
- for (int i = 0; i < 4; i++)
- {
- if (arr[i] > 0)
- min += arr[i];
- }
- int howmany = 0;
- int min_ = n;
- int leftIndex = 0;
- bool breaked = false;
- //while the first letter found that is in the needToFind dictionary
- while (leftIndex < n && !needToFind.ContainsKey(gene[leftIndex]))
- {
- leftIndex++;
- }
- int rightIndex = leftIndex;
- //while all the letters we want to change are found
- //(when the needToFind is empty)
- while (rightIndex < n && needToFind.Count != 0)
- {
- //saving every changeable letter beetween the two index
- if (currenlyHolds.ContainsKey(gene[rightIndex]))
- currenlyHolds[gene[rightIndex]]++;
- howmany++;
- if (needToFind.ContainsKey(gene[rightIndex]))
- {
- needToFind[gene[rightIndex]]--;
- if (needToFind[gene[rightIndex]] == 0)
- needToFind.Remove(gene[rightIndex]);
- }
- rightIndex++;
- }
- //leaving some of the first letters in the substring
- //while we still have enough in it to satisfy the conditions
- while(leftIndex < n && !match(currenlyHolds, needToFind_perma, gene[leftIndex]))
- {
- if (needToFind_perma.ContainsKey(gene[leftIndex]) && needToFind_perma[gene[leftIndex]] != 0)
- currenlyHolds[gene[leftIndex]]--;
- leftIndex++;
- howmany--;
- }
- char saved = ' ';
- if(leftIndex < n)
- //the first letter after the search that we must not leave
- saved = gene[leftIndex];
- if (howmany == min)
- {
- //if the min reached, break, stop the search
- Console.WriteLine(min);
- breaked = true;
- }
- else if( leftIndex < n)
- {
- if (howmany < min_)
- {
- min_ = howmany;
- }
- while (leftIndex < n - min - 1)
- {
- //moving right
- leftIndex++;
- howmany--;
- //same as above
- while (rightIndex < n &&!match(currenlyHolds, needToFind_perma, gene[leftIndex]))
- {
- if (needToFind_perma.ContainsKey(gene[leftIndex]) && needToFind_perma[gene[leftIndex]] != 0)
- currenlyHolds[gene[leftIndex]]--;
- leftIndex++;
- howmany--;
- }
- howmany++;
- //finding the first occurence of the saved letter after the substring
- while (rightIndex < n && gene[rightIndex] != saved)
- {
- if (currenlyHolds.ContainsKey(gene[rightIndex]))
- currenlyHolds[gene[rightIndex]]++;
- rightIndex++;
- howmany++;
- }
- rightIndex++;
- //saving a new letter
- saved = gene[leftIndex];
- if (howmany == min)
- {
- Console.WriteLine(min);
- breaked = true;
- break;
- }
- if (howmany < min_)
- min_ = howmany;
- }
- }
- //if not reached the theoretical minimum
- if (breaked == false)
- Console.WriteLine(min_);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement