P177PROA - ROUND 7A - Một cái đinh rỉ !

P177PROA - ROUND 7A - Một cái đinh rỉ !

Link Sub: https://www.spoj.com/PTIT/problems/P177PROA/
Người Gửi: Dương Lee

  • Problem:

Lúa rất thích Lều, nhưng Lều không muốn xao nhãng việc học. Biết Lúa rất dốt toán, nhất là hình học nên Lều ra cho Lúa một bài toán và nếu Lúa không giải được thì sẽ cho Lúa một cơ hội.  
Lều cho Lúa một hình tròn có bán kính r, tâm của nó được đặt ở tọa độ x0, y0, và một chiếc đinh rỉ. 
Và yêu cầu phải đưa tâm hình tròn đến tọa độ x1,y1.  Biết rằng : Lúa chỉ được di chuyển hình tròn bằng cách cắm chiếc đinh vào mép của hình tròn và xoay hình tròn, và Lúa phải thực hiện với số lần cắm đinh ít nhất.  
Đương nhiên làm sai là chuyện đơn giản, “nhưng hôm nay là cá tháng Tư nên chắc Lều đang nói ngược thôi -_- “ . Hãy giúp Lúa giải bài toán này nhé.
Input
Một dòng duy nhất 5 số nguyên r,x0,y0,x1,y1. (1 ≤ r ≤ 105,  - 105 ≤ x, y, x', y' ≤ 105)
Output
In ra một số nguyên là số lần cắm đinh ít nhất để hoàn thành yêu cầu
Example:
Input
2 0 0 4 0
Output:
1

Input
4 1 2 1 2
Output:
0
Giải thích : Test 2 0 0 4 0
Như hình dưới : sẽ chỉ cần một lần cắm đinh và xoay.
Output:
  • Solution:

Hix, cứ trâu thui bạn :(

  • Code:

C++:

#include <iostream>
#include <math.h>
using namespace std;
 
int main ()
{
    long long r, x0, y0, x1, y1;
    cin>>r>>x0>>y0>>x1>>y1;
    long long d = (x1-x0)*(x1-x0) + (y1-y0)*(y1-y0);
    double k=sqrt(d);
 
    if (x1==x0 && y1==y0)
    {
        cout<<"0";
    }
    else
    {
        if ((k/2)<=r)
            cout<<"1";
        else
        {
            long long dem=0;
            do
            {
                k=k-(double)(r*2);
                dem++;
           }
            while (k/2>r);    		
            
            cout<<dem+1;	
    	}	
    }
    return 0;
}

JAVA:

...

Python:

...

Hướng dẫn tạo và cài đặt SSL Certificate HTTPS (chứng chỉ bảo mật) cho Java servlet Localhost trên Tomcat Server

HTTPS là gì?

HTTPS (Hypertext Transfer Protocol Secure) là giao thức truyền tải siêu văn bản an toàn. Hiểu một cách đơn giản nó là phiên bản nâng cấp của giao thức HTTP tích hợp thêm chứng chỉ bảo mật SSL nhằm mã hóa các thông tin truyền tải tăng tính bảo mật.

Các bước cài đặt

Dưới đây mình sử dụng hệ điều hành Window, eclipse ide để hướng dẫn.

Bước 1: Cài đặt Openssl

Bạn truy cập tại đây đễ xem hướng dẫn cài đặt: Hướng dẫn cài đặt OpenSSL trên Window

Bước 2: Tạo Root Certi

Tạo thư mục để chứa các file key, certi, ... và mở cmd trên thư mục đó và nhập như dưới đây

 openssl req -x509 -nodes -new -sha256 -days 1024 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=US/CN=Example-Root-CA"


openssl x509 -outform pem -in RootCA.pem -out RootCA.crt


Sau khi thực hiện đầy đủ các bước trên bạn có một thư mục chứa các file như sau:


Bước 3: Tạo domain certificate:

Tiếp đến bạn tạo một file có tên là: domains.ext ngay trên thư mục đó với nội dung như sau:

authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = localhost



Tiếp theo bạn tiếp tục mở cmd trên thư mục đó để nhập các câu lệnh sau:

openssl req -new -nodes -newkey rsa:2048 -keyout localhost.key -out localhost.csr -subj "/C=US/ST=YourState/L=YourCity/O=Example-Certificates/CN=localhost.local"

openssl x509 -req -sha256 -days 1024 -in localhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out localhost.crt


Sau khi hoàn tất ta có file trong thư mục như sau:


Bước 4: Install Certificate

Các bạn làm theo các bước sau để cài Certi trên Win

 Chuột phải vào RootCA.crt chọn Install



Chọn Trusted Root Certification Authorities


Bước 5: Config Server Tomcat

 Truy cập vào thư mục chứa Tomcat và sửa file sau: <folder-tomcat>/conf/server.xml


Chèn đoạn mã dưới đây. Lưu ý: sửa đúng đường dẫn thư mục bạn chứa các file certi

<Connector

      protocol="org.apache.coyote.http11.Http11AprProtocol"

      port="8443"

      maxThreads="200"

      scheme="https"

      secure="true"

      SSLEnabled="true"

      SSLCertificateFile="C:\SSL\test\localhost.crt"

      SSLCertificateKeyFile="C:\SSL\test\localhost.key"

      SSLVerifyClient="optional"

      SSLProtocol="TLSv1.2"/>




Xóa Server cũ (xóa config cũ) rồi chạy lại Server



Bước 6: Check kết quả



Một số lưu ý khi cài đặt và config:

Đảm bảo rằng tất cả các thư viện css, js bạn sử dụng bên ngoài phải sử dụng https://

Đảm bảo rằng trong thư mục /bin của Tomcat chứa thư viện tcnative-1.dll (Apache Tomcat Native library). Nếu không có hoặc đã quá cũ bạn có thể tải về tại đây và cop vào thư mục của bạn: Apache Tomcat Native library 1.2.25




Hướng dẫn cài đặt OpenSSL trên Window

 OpenSSL là gì?

OpenSSL là một thư viện phần mềm cho các ứng dụng bảo mật truyền thông qua mạng máy tính chống nghe trộm hoặc cần phải xác định phe truyền thông ở bên đầu kia. Nó được sử dụng rộng rãi trong các máy chủ web internet, phục vụ phần lớn tất cả các trang web.
Trong bài viết dưới đây sẽ hướng dẫn bạn cài OpenSSL trên Window phục vụ cho việc generate key khi bạn cần bảo mật hoặc cài các chứng chỉ cần thiết cho website của bạn.

 Các bước cài đặt:

Bước 1: Truy cập vào: https://slproweb.com/products/Win32OpenSSL.html chọn phiên bản win32/win64 phù hợp với máy của bạn.


Sau khi cài đặt bạn sẽ thấy thư mục openssl được cài như sau:
C:\Program Files\OpenSSL-Win64

Bước 2: Tiếp theo bạn mở cài đặt Environment của window thêm cài đặt đường dẫn cho openssl như sau:
Search từ khóa Env, sau đó chọn Edit the system environment variables

Chọn Environment Variables

Chỉnh sửa Path trong System variables

Thêm đường dẫn \bin vừa mới cài bên trên

Bước 3: Thử chạy openssl trên cmd

Type: "cmd" trên thanh đường dẫn ở bất kỳ thư mục nào trên Win và nhấn <Enter>

Nhập openssl để check

Vậy là thành công rùi, thankiu các bạn đã theo dõi...
PTIT018A - ACM PTIT 2018 A - CẶP SỐ NGUYÊN TỐ ĐẶC BIỆT

PTIT018A - ACM PTIT 2018 A - CẶP SỐ NGUYÊN TỐ ĐẶC BIỆT

Link Sub: https://www.spoj.com/PTIT/problems/PTIT018A/
Người Gửi: Dương Lee

  • Problem:

Cặp số nguyên tố P, Q được gọi là cặp nguyên tố đặc biệt nếu P và Q là nguyên tố và hơn kém nhau 6 đơn vị. Ví dụ các cặp nguyên tố (11, 17), (13, 19) được gọi là cặp nguyên tố đặc biệt. Hãy đếm tất cả các cặp nguyên tố đặc biệt trong khoảng [L, R].
Ví dụ L=6, R=59 ta có 10 cặp nguyên tố đặc biệt là (7, 13), (11, 17), (13,19), (17, 23), (23, 29), (31, 37), (37, 43), (41, 47), (47, 53), (53, 59).

Input
Dòng đầu tiên là số lượng bộ test T (T≤100).
Mỗi bộ test gồm 2 số nguyên L, R (2≤L, R≤10^6).
Output
Với mỗi test in ra số cặp nguyên tố tìm được trên một dòng
Example:
Input
3
11 19
6 59
2 1000000
Output:
2
10
16386

  • Solution:

- Sử dụng sàng nguyên tố: Khởi tạo được một mảng đánh dấu các số là số nguyên tố (snt[], trong đó nếu snt[i]=1 thì i là số nguyên tố)
- Trong một khoảng L, R: (i:=L->R) ta có một cặp nếu số thứ i và số thứ i+6 là cùng là số nguyên tố (snt[i]=1 && snt[i+1]=1) 

  • Code:

C++:

#include <iostream>
#include <math.h>
using namespace std;
 
#define MAX 1000000
int snt[MAX+10];
int mcd[MAX+10];
 
int sont(int n)
{
    if (n<2)
        return 0;
    for (int i=2; i<=sqrt(n); i++)
    {
    	if (n%i==0)
    	{
            return 0;
    	}
    }
    return 1;
}
 
void init()
{
    for (int i=1; i<=MAX; i++)
    {
        snt[i] = 1;
        mcd[i] = 0;
    }
}
 
void sangnt()
{
    snt[0] = 0;
    snt[1] = 0;
    for (int i=2; i<=sqrt(MAX); i++)
    {
        if (snt[i] == 1)
        {
            for (int j=2; j<=MAX/i; j++)
            {
                snt[i*j] = 0;
            }
        }
    }
}
 
 
int main()
{
    init();
    sangnt();
    int t;
    cin>>t;
    while(t--)
    {
        int a, b;
        cin>>a>>b;
        int ts = 0;
        for (int i=a; i<=b; i++)
        {
            if (snt[i]==1 && snt[i+6]==1 && i+6<=b)
            {
                ts++;
            }
        }
        cout<<ts<<endl;
    }
    return 0;
}

JAVA:

...

Python:

...
P164PROG - ROUND 4G - Kim tự tháp

P164PROG - ROUND 4G - Kim tự tháp

Link Sub: https://www.spoj.com/PTIT/problems/P164PROG/
Người Gửi: Dương Lee

  • Problem:

LB có n khối hộp lập phương và anh ta quyết định xếp nó thành hình kim tự tháp. Kim tự tháp tầng trên cùng có 1 khối, tầng thứ 2 có 1 + 2 = 3 khối, tầng thứ 3 có 1 + 2 + 3 = 6 khối, cứ như vậy cho các đỉnh ở dưới. LB muốn xác định với n khối hộp, chiều cao tối đa của kim tự tháp là bao nhiêu?
Input
Một dòng chứa số n ( 1 <= n <= 10^4).
Output
Đáp án của bài toán.
Example:
Input
1
Output:
1

Input
25
Output:
4
  • Solution:

Bài này while cộng dồn cho đến khi đủ là ok ^^

  • Code:

C++:

https://ideone.com/ZkdEQx
#include <iostream>
using namespace std;
 
int main ()
{
    int n;
    cin>>n;
    int s=0;
    int t=0;
    int bs=0;
    while (s<n)
    {
        t++;
        bs=bs+t;
        s=s+bs;
    }
    if (s==n)
        cout<<t;
    else if (s>n)
        cout<<(t-1);
        
    return 0;
}

JAVA:

...

Python:

...
P176PROH - ROUND 6H - Bạn bè

P176PROH - ROUND 6H - Bạn bè

Link Sub: https://www.spoj.com/PTIT/problems/P176PROH/
Người Gửi: Dương Lee

  • Problem:

Hiện có ba người bạn sinh sống trên đường thẳng Ox ‎‎tại Hà Nội. Người đầu tiên sống tại điểm ‎‎x‎‎1‎‎, người thứ hai sống tại điểm ‎‎x‎‎2‎‎, và ba người bạn sống tại điểm ‎‎x‎‎3‎‎. Họ có kế hoạch để ăn mừng năm mới cùng với nhau, vì vậy họ cần phải gặp nhau tại một điểm.  
Nhiệm vụ của ban là tính Tổng khoảng cách tối thiểu mà họ cần đi để chào mừng năm mới cùng nhau. Input đảm bảo rằng câu trả lời tối ưu luôn luôn là số nguyên.‎
Input
Dòng đầu tiên chứa só lượng bộ test t. 
T dòng sau, mỗi dòng chứa ba số nguyên ‎‎phân biệt ‎‎x‎‎1‎‎, ‎‎x‎‎2‎‎ và ‎‎x‎‎3‎ (‎1 ≤ ‎‎x‎‎1‎‎, ‎‎x‎‎2‎‎, ‎‎x‎‎3‎‎ ≤ 100‎‎) là tọa độ của ngôi nhà đầu tiên, thứ hai và thứ ba tương ứng (tọa độ có giá trị tuyệt đối <= 10^18). 
Output
In một số nguyên duy nhất là khoảng cách tối thiểu tất cả các bạn bè cần để đi để chào mừng năm mới cùng nhau.
Example:
Input
2
7 1 4
30 20 10
Output:
6
20

  • Solution:

Xét tất cả các trường hợp khoảng cách của 3 điểm. Khoảng cách tối thiểu nhỏ nhất là tổng hai khoảng cách nhỏ nhất trong tất cả các trường hợp. 

  • Code:

C++:

https://ideone.com/HWeEfx
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;
 
int main ()
{
    long long t;
    cin>>t;
    long long x1, x2, x3;
    long long a[3];
    for (long long i=1; i<=t; i++)
    {
        cin>>x1>>x2>>x3;
        
        a[0]=abs(x1-x2);
        a[1]=abs(x1-x3);
        a[2]=abs(x2-x3);
        
        sort (a, a+3);
        cout<<a[0]+a[1]<<endl;
    }
    return 0;
}

JAVA:

...

Python:

...
 P176PROG - ROUND 6G - Số phần tử khác nhau

P176PROG - ROUND 6G - Số phần tử khác nhau

Link Sub: https://www.spoj.com/PTIT/problems/P176PROG/
Người Gửi: Dương Lee

  • Problem:

Cho 4 số tự nhiên n, x, y, z (y < z).
Dãy số a được tạo ra như sau:
a[1] = x % z;
for (int i = 2; i <= n; i++)
    a[i] = (a[i – 1] + y) % z;
Hãy đếm số phần tử khác nhau của dãy số a.
Input
gồm 1 dòng chứa 4 số tự nhiên n, x, y, z (1 <= x, y, z <= 109; 1 <= n <= 108).
Output
1 số tự nhiên duy nhất là số phần tử khác nhau của dãy số a
Example:
Input
5 1 3 5
Output:
5

  • Solution:

Hack :v

  • Code:

C++:

https://ideone.com/461bZq
#include <iostream>
using namespace std;
 
int main ()
{
    long long n, x, y, z;
    cin>>n>>x>>y>>z;
    
    long long tg=z;
    while(y!=z)
    {
        if(y>z)
            y=y-z;
        else
            z=z-y;
    }
    
    if (tg/y<n) cout<<(tg/y);
    else cout<<n;
    return 0;
}

JAVA:

...

Python:

...
P145SUMH - ROUND 5H - Hệ thống điện

P145SUMH - ROUND 5H - Hệ thống điện

Link Sub: https://www.spoj.com/PTIT/problems/P145SUMH/
Người Gửi: Dương Lee

  • Problem:

Khu vực nhà Tí bị mất điện dài ngày để khắc phục sự cố đường dây 500 kV. Các kỹ sư bảo rằng khu vực này có khi mất điện đến cả tháng trời. Vì vậy, các hộ dân ở đây đã sử dụng máy phát điện. Không phải hộ gia đình nào cũng có, vì vậy, họ đã kết nối với nhau để tạo thành hệ thống lưới điện riêng. Rõ ràng những gia đình nào ở càng xa nguồn phát thì điện sẽ càng yếu.  
Tí muốn biết xem trong khu vực của mình, gia đình nào điện sẽ yếu nhất?  
Độ yếu của điện tại hộ gia đình X được tính bằng 0 nếu hộ đó là hộ phát điện, nếu hộ X có kết nối điện với hộ Y mà hộ Y ở gần máy phát hơn, độ yếu tại hộ X = độ yếu tại hộ Y + 1. Nếu hộ X không có điện thì có độ yếu bằng vô cùng (infinity).
Input
Dòng đầu tiên gồm 3 số nguyên N, M, H lần lượt là số hộ gia đình, M là số hộ gia đình có máy phát điện, H là số kết nối 2 chiều. (N, M <= 1 000, H <= 10 000).  
Dòng tiếp theo gồm M số là ID các hộ gia đình có máy phát điện (ID đánh số từ 0 tới N-1).  
H dòng tiếp theo, mỗi dòng gồm 2 số u, v, cho biết hộ gia đình u có kết nối với hộ gia đình.
Output
In ra hộ gia đình có độ yếu của điện là cao nhất. Nếu có nhiều đáp án, in ra hộ có ID nhỏ nhất.
Example:
Input
6 3 5
0 5 2
0 1
1 2
4 5
3 5
0 2
Output:
1

Input
6 2 3
5 2
0 5
0 1
3 4
Output:
3
  • Solution:

Ban đầu coi tất cả các hộ gia đình có độ yếu của điện là: infinity (>1000 - vì chỉ có tối đa 1000 hộ)
Bài này sau khi setup hệ thống đường dây điện (chính là biểu diễn các hộ gia đình theo danh sách kề - biểu diễn đồ thị)
Chỉ cần BFS từ các điểm phát phát đếm bước đi ngắn nhất đến các căn hộ khác. Điện của max của mỗi hộ = min(tất cả trường hợp yếu điện từ nguồn phát đến hộ đó)
Cuối cùng độ yếu điện lớn nhất chính là max(điện tất cả các hộ).

  • Code:

C++:

https://ideone.com/C1yMXV
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int n, m, h;
vector< int > generator;
vector< int > line[1003];

void Read()
{
    cin>>n>>m>>h;
    for (int i=0; i<m; i++)
    {
        int tmp;
        cin>>tmp;
        generator.push_back(tmp);
    }
    for (int i=0; i<h; i++)
    {
        int a, b;
        cin>>a>>b;
        line[a].push_back(b);
        line[b].push_back(a);
    }
}

int weak[1003];

void Init()
{
    for (int i=0; i<n; i++)
    {
        weak[i] = 1003;
    }
}

int check[1003];
int trans[1003];
void Reset()
{
    for (int i=0; i<n; i++)
    {
        check[i] = 0;
        trans[i] = -1;
    }
}

void BFS(int u)
{
    check[u] = 1;
    queue<int> q;
    q.push(u);
    trans[u] = 0;
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        for (int i=0; i<line[u].size(); i++)
        {
            int v = line[u][i];
            if (check[v] == 0)
            {
                q.push(v);
                check[v] = 1;
                trans[v] = trans[u] + 1;
            }
        }
    }
}

void CheckWeak()
{
    for (int i=0; i<n; i++)
    {
        if (trans[i]!=-1)
        {
            if (trans[i]<weak[i])
            {
                weak[i] = trans[i];
            }
        }
    }
}

void OUT()
{
    int p = 0;
    for (int i=1; i<n; i++)
    {
        if (weak[i] > weak[p])
        {
            p = i;
        }
    }
    cout<<p;
}

void Test()
{
    for (int i=0; i<n; i++)
    {
        cout<<check[i]<<" ";
    }
    cout<<endl;
    for (int i=0; i<n; i++)
    {
        cout<<trans[i]<<" ";
    }
    cout<<endl;
    for (int i=0; i<n; i++)
    {
        cout<<weak[i]<<" ";
    }
}



int main()
{
//    freopen("input.txt", "r", stdin);
    Read();
    Init();
    for (int i=0; i<m; i++)
    {
        Reset();
        BFS(generator[i]);
        CheckWeak();
    }
    OUT();
//    test();
    return 0;
}

JAVA:

...

Python:

...
P141SUMF - ROUND 1F - Ném đá

P141SUMF - ROUND 1F - Ném đá

Link Sub: https://www.spoj.com/PTIT/problems/P141SUMF/
Người Gửi: Dương Lee

  • Problem:

Trong khoảng 2 tuần, Zoro phải nằm trên giường vì bị bạn Nami vô tình ném 1 viên đá to vào chân trái. Vì Zoro đã hoàn thành hết nhiệm vụ nên anh ta phải tìm cách để giết thời gian.  
Trò chơi mới của Zoro được chơi trên 1 bảng kích thước R X C. Ban đầu, mỗi ô vuông được để trống hoặc bị chặn bởi 1 bức tường. Zoro ném 1 viên đá vào bảng bằng cách để nó vào hàng trên cùng của 1 cột và để trọng lực làm làm phần còn lại.  
Trọng lực hoạt động như sau: 
- Nếu ô vuông bên dưới viên đá là 1 bức tường chắn, hoặc nếu viên đá ở hàng cuối cùng của một cột thì nó ở yên chỗ đó.  
- Nếu ô vuông bên dưới viên đá để trống, nó sẽ di chuyển xuống ô đó.  
- Nếu ô vuông bên dưới viên đá, có 1 viên đá khác, viên đá có thể trượt sang 2 bên như sau:     
+ Nếu ô vuông bên trái, và ô dưới của ô bên trái trống, viên đá sẽ trượt sang ô bên trái.     
+ Nếu viên đá không trượt sang trái và ô vuông bên phải, ô dưới của ô bên phải trống, viên đá sẽ trượt sang phải.     
+ Còn lại, viên đá sẽ ở yên đó, và không di chuyển nữa.  
Zoro không bao giờ ném viên đá khác, khi viên đá trước chưa rơi cố định vào 1 ô nào đó.  
Viết 1 chương trình, vẽ cái bảng sau khi Zoro ném toàn bộ số viên đá của mình vào đó, giả sử chúng ta biết Zoro ném đá vào các cột, theo thứ tự.  
Chú ý : Zoro không bao giờ ném 1 viên đá vào 1 cột, nếu ô trên cùng của cột đó không trống.
Input
Dòng đầu tiên chứa số nguyên R và C, là kích thước của bảng (R, C <= 30).  
Mỗi dòng trong N dòng tiếp theo, chứa C kí tự, là sơ đồ ban đầu của bảng. Dấu '.' đại diện cho 1 ô trống, trong khi 'X' là 1 ô được chặn bởi tường.  
Dòng kế tiếp chứa số nguyên N, là số viên đá mà Zoro ném.  
Mỗi N dòng tiếp theo chứa 1 số nguyên giữa 1 và C, là cột mà Zoro ném viên đá vào (đánh số từ trái sang phải).
Output
In ra R dòng, mỗi dòng chứa C kí tự, là sơ đồ của bảng sau khi đã ném hết đá vào. Đá được kí hiệu bằng chữ cái “O”.
Example:
Input
5 4
....
....
X...
....
....
4
1
1
1
1
Output:
....
O...
X...
....
OOO.

Input
7 6
......
......
...XX.
......
......
.XX...
......
6
1
4
4
6
4
4
Output:
......
...O..
...XX.
......
.OO...
.XX...
O..O.O
  • Solution:

Bài này sử dụng đệ quy để tìm đường tiếp theo cho viên đá (Dựa vào dữ kiện của đề cung cấp là được).
Để tiện hơn thì mình tạo thêm một hàng rào 'X' bao xung quanh nữa để đỡ phải xét nhiều điều kiện. 
VD: 
Map:
...X.
.....
Thì giờ sẽ thành:
XXXXXXX
X...X.X
X.....X
XXXXXXX

  • Code:

C++:

https://ideone.com/SULbQ2
#include <iostream>
#include <vector>
using namespace std;

int r, c;
char m[35][35];
vector <int> v;

void read()
{
    cin>>r>>c;
    for (int i=0; i<=r+1; i++)
    {
        for (int j=0; j<=c+1; j++)
        {
            if (i==0 || i==r+1 || j==0 || j==c+1)
                m[i][j] = 'X';
            else
            {
                cin>>m[i][j];
            }
        }
    }

    int n;
    cin>>n;
    for (int i=0; i<n; i++)
    {
        int a;
        cin>>a;
        v.push_back(a);
    }
}

int findWay(int i, int j)
{
    if (m[i+1][j] == 'X')
    {
        m[i][j] = 'O';
        return 1;
    }
    else if (m[i+1][j] == '.')
    {
        findWay(i+1, j);
    }
    else if (m[i+1][j] == 'O')
    {
        if (m[i][j-1] == '.' && m[i+1][j-1] == '.')
        {
            findWay(i+1, j-1);
            return 1;
        }
        else if (m[i][j+1]=='.' && m[i+1][j+1] == '.')
        {
            findWay(i+1, j+1);
            return 1;
        }
        else
        {
            m[i][j] = 'O';
            return 1;
        }
    }
}

void out()
{
    for (int i=1; i<=r; i++)
    {
        for (int j=1; j<=c; j++)
        {
            cout<<m[i][j];
        }
        cout<<endl;
    }
}

void check()
{
    cout<<r<<" "<<c<<endl;
    for (int i=0; i<=r+1; i++)
    {
        for (int j=0; j<=c+1; j++)
        {
            cout<<m[i][j];
        }
        cout<<endl;
    }
    cout<<v.size()<<endl;
    for (int i=0; i<v.size(); i++)
        cout<<v[i]<<endl;
}

int main()
{
//    freopen("input.txt", "r", stdin);
    read();
    for (int i=0; i<v.size(); i++)
    {
        findWay(1, v[i]);
    }
    out();
//    check();
    return 0;
}

JAVA:

...

Python:

...