Problem:
Score: 400 points

Problem Statement

AtCoder Inc. has decided to lock the door of its office with a 3-digit PIN code.

The company has an N-digit lucky number, S. Takahashi, the president, will erase N-3 digits from S and concatenate the remaining 3 digits without changing the order to set the PIN code.

How many different PIN codes can he set this way?

Both the lucky number and the PIN code may begin with a 0.

Constraints

4 \leq N \leq 30000

S is a string of length N consisting of digits.

Input

Input is given from Standard Input in the following format:

N
S

Output

Print the number of different PIN codes Takahashi can set.

Sample Input 1

4
0224

Sample Output 1

3

Takahashi has the following options:

Erase the first digit of S and set 224.

Erase the second digit of S and set 024.

Erase the third digit of S and set 024.

Erase the fourth digit of S and set 022.

Thus, he can set three different PIN codes: 022, 024, and 224.

Sample Input 2

6
123123

Sample Output 2

17

Sample Input 3

19
3141592653589793238

Sample Output 3

329

Solution in Rust (1.15.1) (judge verdict: Accepted)

#![allow(unused_macros, deprecated)]

#[allow(dead_code)]
mod utils {
    use std::io::{
        self, BufRead, BufReader, BufWriter, Seek, SeekFrom, Stdin, StdinLock, Stdout, StdoutLock,
        Write,
    };
    use std::mem;
    use std::ops::{Deref, DerefMut};
    use std::ptr;
    use std::slice;
    use std::str::{self, FromStr};

    #[inline]
    fn is_space_or_line_break(b: &u8) -> bool {
        *b == b' ' || *b == b'\n'
    }

    pub struct Scanner<R: BufRead> {
        reader: R,
        buf: Vec<u8>,
    }

    impl<R: BufRead> Scanner<R> {
        #[inline]
        pub fn new(reader: R) -> Scanner<R> {
            Scanner {
                reader: reader,
                buf: Vec::with_capacity(100),
            }
        }

        pub fn read<T: FromStr>(&mut self) -> T {
            self.read_until(is_space_or_line_break);
            self.parse()
        }

        pub fn read2<T1: FromStr, T2: FromStr>(&mut self) -> (T1, T2) {
            (self.read(), self.read())
        }

        pub fn read3<T1: FromStr, T2: FromStr, T3: FromStr>(&mut self) -> (T1, T2, T3) {
            (self.read(), self.read(), self.read())
        }

        pub fn read4<T1: FromStr, T2: FromStr, T3: FromStr, T4: FromStr>(
            &mut self,
        ) -> (T1, T2, T3, T4) {
            (self.read(), self.read(), self.read(), self.read())
        }

        pub fn reads(&mut self) -> &str {
            self.read_until(is_space_or_line_break);
            unsafe { str::from_utf8_unchecked(&self.buf) }
        }

        pub fn readl(&mut self) -> &str {
            self.buf.clear();
            self.reader.read_until(b'\n', &mut self.buf).unwrap();
            let bytes = if self.buf.last() == Some(&b'\n') {
                &self.buf[..self.buf.len() - 1]
            } else {
                &self.buf
            };
            unsafe { str::from_utf8_unchecked(&bytes) }
        }

        pub fn read_vec<T: FromStr>(&mut self, count: usize) -> Vec<T> {
            (0..count).map(|_| self.read()).collect()
        }

        fn read_until<P: FnMut(&u8) -> bool>(&mut self, mut predicate: P) {
            self.buf.clear();
            let mut first = true;

            // https://doc.rust-lang.org/src/std/io/mod.rs.html#1623-1649
            loop {
                let (done, used) = {
                    let available = self.reader.fill_buf().unwrap();
                    if first && available.len() == 0 {
                        panic!("Scan Error (EOF reached)");
                    }

                    match available.iter().position(&mut predicate) {
                        Some(0) if first => (false, 1),
                        Some(i) => {
                            self.buf.extend_from_slice(&available[..i]);
                            (true, i + 1)
                        }
                        None => {
                            self.buf.extend_from_slice(available);
                            (false, available.len())
                        }
                    }
                };

                self.reader.consume(used);
                if done || used == 0 {
                    return;
                }

                first = false;
            }
        }

        #[inline]
        fn parse<T: FromStr>(&mut self) -> T {
            // 文字列をT型へパースする
            let elem = unsafe { str::from_utf8_unchecked(&self.buf) };
            elem.parse()
                .unwrap_or_else(|_| panic!(format!("failed parsing: {}", elem)))
        }
    }

    impl<R: BufRead + Seek> Seek for Scanner<R> {
        #[inline]
        fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
            self.reader.seek(pos)
        }
    }

    pub struct StdinScanner {
        stdin: Stdin,
        scanner: Scanner<BufReader<StdinLock<'static>>>,
    }

    impl StdinScanner {
        #[inline]
        pub fn new() -> StdinScanner {
            let stdin = io::stdin();
            let stdinlock = unsafe { mem::transmute(stdin.lock()) };
            let reader = BufReader::with_capacity(4096, stdinlock);
            let scanner = Scanner::new(reader);
            StdinScanner {
                stdin: stdin,
                scanner: scanner,
            }
        }
    }

    impl Deref for StdinScanner {
        type Target = Scanner<BufReader<StdinLock<'static>>>;

        #[inline]
        fn deref(&self) -> &Self::Target {
            &self.scanner
        }
    }

    impl DerefMut for StdinScanner {
        #[inline]
        fn deref_mut(&mut self) -> &mut Self::Target {
            &mut self.scanner
        }
    }

    pub struct StdoutWriter {
        stdout: Stdout,
        writer: BufWriter<StdoutLock<'static>>,
    }

    impl StdoutWriter {
        #[inline]
        pub fn new() -> StdoutWriter {
            let stdout = io::stdout();
            let stdoutlock = unsafe { mem::transmute(stdout.lock()) };
            let writer = BufWriter::with_capacity(4096, stdoutlock);
            StdoutWriter {
                stdout: stdout,
                writer: writer,
            }
        }

        pub fn write<T: Writable>(&mut self, v: T) {
            v.display(&mut self.writer);
        }

        pub fn writeln<T: Writable>(&mut self, v: T) {
            v.display(&mut self.writer);
            self.writer.write_all(b"\n").unwrap();
        }

        pub fn write_horizontal<I>(&mut self, iter: I)
        where
            I: IntoIterator,
            I::Item: Writable,
        {
            let mut it = iter.into_iter();
            if let Some(elem) = it.next() {
                elem.display(&mut self.writer);
            } else {
                return;
            }

            for elem in it {
                elem.display(&mut self.writer);
                self.writer.write_all(b" ").unwrap();
            }
        }

        pub fn write_vertical<I>(&mut self, iter: I)
        where
            I: IntoIterator,
            I::Item: Writable,
        {
            let mut it = iter.into_iter();
            if let Some(elem) = it.next() {
                elem.display(&mut self.writer);
            } else {
                return;
            }

            for elem in it {
                elem.display(&mut self.writer);
                self.writer.write_all(b"\n").unwrap();
            }
        }
    }

    impl Write for StdoutWriter {
        #[inline]
        fn flush(&mut self) -> io::Result<()> {
            self.writer.flush()
        }

        #[inline]
        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
            self.writer.write(buf)
        }
    }

    static DEC_DIGITS_LUT: &'static [u8; 200] = b"0001020304050607080910111213141516171819\
            2021222324252627282930313233343536373839\
            4041424344454647484950515253545556575859\
            6061626364656667686970717273747576777879\
            8081828384858687888990919293949596979899";

    fn write_int<W: Write>(mut writer: W, mut n: u64, is_negative: bool) {
        unsafe {
            let mut buf: [u8; 39] = mem::uninitialized();
            let buf_ptr_start = buf.as_mut_ptr().offset(39);
            let mut buf_ptr = buf_ptr_start;
            let lut_ptr = DEC_DIGITS_LUT.as_ptr();

            while n >= 10000 {
                let rem = (n % 10000) as isize;
                n /= 10000;

                let d1 = (rem / 100) << 1;
                let d2 = (rem % 100) << 1;
                buf_ptr = buf_ptr.offset(-4);
                ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr, 2);
                ptr::copy_nonoverlapping(lut_ptr.offset(d2), buf_ptr.offset(2), 2);
            }

            let mut n = n as isize; // possibly reduce 64bit math

            // decode 2 more chars, if > 2 chars
            if n >= 100 {
                let d1 = (n % 100) << 1;
                n /= 100;
                buf_ptr = buf_ptr.offset(-2);
                ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr, 2);
            }

            // decode last 1 or 2 chars
            if n < 10 {
                buf_ptr = buf_ptr.offset(-1);
                *buf_ptr = (n as u8) + b'0';
            } else {
                let d1 = n << 1;
                buf_ptr = buf_ptr.offset(-2);
                ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr, 2);
            }

            if is_negative {
                buf_ptr = buf_ptr.offset(-1);
                *buf_ptr = b'-';
            }

            let buf_slice =
                slice::from_raw_parts(buf_ptr, buf_ptr_start as usize - buf_ptr as usize);

            writer.write_all(buf_slice).unwrap();
        }
    }

    pub trait Writable {
        fn display<W: Write>(&self, writer: &mut W);
    }

    impl Writable for str {
        #[inline]
        fn display<W: Write>(&self, writer: &mut W) {
            writer.write_all(self.as_bytes()).unwrap()
        }
    }

    impl<'a> Writable for &'a str {
        #[inline]
        fn display<W: Write>(&self, writer: &mut W) {
            writer.write_all(self.as_bytes()).unwrap()
        }
    }

    impl Writable for String {
        #[inline]
        fn display<W: Write>(&self, writer: &mut W) {
            writer.write_all(self.as_bytes()).unwrap()
        }
    }

    impl Writable for bool {
        #[inline]
        fn display<W: Write>(&self, writer: &mut W) {
            let s: &'static [u8] = if *self { b"Yes" } else { b"No" };
            writer.write_all(s).unwrap();
        }
    }

    macro_rules! impl_writable_int {
        ($($int:ty)*) => {
            $(
                impl Writable for $int {
                    #[allow(unused_comparisons)]
                    fn display<W: Write>(&self, writer: &mut W) {
                        let is_negative = !(*self >= 0);
                        let abs = if is_negative {
                            (!*self as u64).wrapping_add(1)
                        } else {
                            *self as u64
                        };
                        write_int(writer, abs, is_negative);
                    }
                }
            )*
        };
    }

    macro_rules! impl_writable_float {
        ($($float:ty)*) => {
            $(
                impl Writable for $float {
                    #[inline]
                    fn display<W: Write>(&self, writer: &mut W) {
                        write!(writer, "{}", *self).unwrap();
                    }
                }
            )*
        }
    }

    impl_writable_int!(u8 u16 u32 u64 usize i8 i16 i32 i64 isize);
    impl_writable_float!(f32 f64);

    pub static mut SCANNER: *mut StdinScanner = 0 as *mut StdinScanner;
    pub static mut WRITER: *mut StdoutWriter = 0 as *mut StdoutWriter;

    #[inline]
    pub fn atcoder_initialize() {
        unsafe {
            SCANNER = mem::transmute(Box::new(StdinScanner::new()));
            WRITER = mem::transmute(Box::new(StdoutWriter::new()));
        }
    }

    #[inline]
    pub fn atcoder_finish() {
        unsafe {
            (*WRITER).flush().unwrap();
        }
    }
}

macro_rules! input {
    () => {};
    (@scanner $scanner:ident, @pred [ $($pred:tt)* ], ($var1:tt, $var2:tt) : [($t1:tt, $t2:tt) ; $len:expr]) => {
        let mut $var1 = Vec::with_capacity($len as usize);
        let mut $var2 = Vec::with_capacity($len as usize);

        for _ in 0..$len {
            $var1.push(scan!($scanner, $t1));
            $var2.push(scan!($scanner, $t2));
        }
    };
    (@scanner $scanner:ident, @pred [ $($pred:tt)* ], $var:tt : $t:tt) => {
        let $($pred)* $var = scan!($scanner, $t);
    };
    (@scanner $scanner:ident,) => {};
    (@scanner $scanner:ident, $var:tt : $t:tt) => {
        input!(@scanner $scanner, @pred [], $var : $t);
    };
    (@scanner $scanner:ident, mut $var:tt : $t:tt) => {
        input!(@scanner $scanner, @pred [mut], $var : $t);
    };
    (@scanner $scanner:ident, $var:tt : $t:tt, $($r:tt)*) => {
        input!(@scanner $scanner, $var : $t);
        input!(@scanner $scanner, $($r)*);
    };
    (@scanner $scanner:ident, mut $var:tt : $t:tt, $($r:tt)*) => {
        input!(@scanner $scanner, mut $var : $t);
        input!(@scanner $scanner, $($r)*);
    };
    ($($r:tt)*) => {
        let scanner_ref = unsafe { &mut *$crate::utils::SCANNER };
        input!(@scanner scanner_ref, $($r)*);
    }
}

macro_rules! scan {
    ($scanner:ident, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| scan!($scanner, $t)).collect::<Vec<_>>()
    };
    ($scanner:ident, usize1) => {
        scan!($scanner, usize) - 1
    };
    ($scanner:ident, line) => {
        $scanner.readl().to_string()
    };
    ($scanner:ident, $t:ty) => {
        $scanner.read::<$t>()
    };
}

macro_rules! pprint {
    ($value:expr) => {
        unsafe {
            (*$crate::utils::WRITER).write($value);
        }
    };
    ($value:expr, $($r:tt)*) => {
        let writer = unsafe { &*$crate::utils::WRITER };
        writer.write($value);
        writer.write(" ");
        pprint!($($r)*);
    };
}

macro_rules! pprintln {
    ($value:expr) => {
        unsafe {
            (*$crate::utils::WRITER).writeln($value);
        }
    };
    ($value:expr, $($r:tt)*) => {
        let writer = unsafe { &*$crate::utils::WRITER };
        writer.write($value);
        writer.write(" ");
        pprintln!($($r)*);
    };
}

macro_rules! atcoder_main {
    ($func:ident) => {
        fn main() {
            $crate::utils::atcoder_initialize();
            $func();
            $crate::utils::atcoder_finish();
        }
    };
}

fn run() {
    input! {
        n: usize,
        s: String
    }

    let s: Vec<u16> = s.bytes().map(|v| (v - b'0') as u16).collect();

    let mut count = 0;
    'outer: for i in 0..1000 {
        let mut current_digit = i / 100;
        let mut current_digit_idx = 0;

        for si in &s {
            if *si == current_digit {
                if current_digit_idx == 2 {
                    count += 1;
                    continue 'outer;
                }

                current_digit_idx += 1;
                current_digit = if current_digit_idx == 1 {
                    i / 10 % 10
                } else {
                    i % 10
                };
            }
        }
    }

    pprintln!(count);
}

atcoder_main!(run);