「CF623X」AIM Tech Round (Div. 1)
A. Graph and String
题意
n个点,每个点有a,b,c其中一种颜色,若两个点颜色的字母相邻则它们之间连边。
给出图的连边情况,求一种可行的染色方案。
题解
如果有一个点和其它点都有连边,将其标号b。
然后选择一个未被标号的点,标号为a,二分图染色。
最后验证一下即可。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | #include<map> #include<set> #include<cmath> #include<stack> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define pi acos(-1) #define mod 10000007 #define inf 1000000000 #define ll long long using namespace std; ll read() {     ll x=0,f=1;char ch=getchar();     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}     return x*f; } int n,m; bool e[505][505]; int v[505]; void solve(int x,int y) {     for(int i=1;i<=n;i++)         if(i!=x&&i!=y)         {             if(e[i][x])v[i]=1;             if(e[i][y])v[i]=3;             if(e[i][x]&&e[i][y])v[i]=2;         }             } int main() {     n=read();m=read();     for(int i=1;i<=m;i++)     {         int u=read(),v=read();         e[u][v]=e[v][u]=1;     }     bool flag=0;     for(int i=1;i<=n;i++)         for(int j=i+1;j<=n;j++)             if(!e[i][j])             {                 v[i]=1;v[j]=3;                 solve(i,j);                 flag=1;                 break;             }     if(!flag)for(int i=1;i<=n;i++)v[i]=1;     for(int i=1;i<=n;i++)if(!v[i]){puts("No");return 0;}     for(int i=1;i<=n;i++)         for(int j=i+1;j<=n;j++)         {             if(abs(v[i]-v[j])<=1&&!e[i][j]){puts("No");return 0;}             if(abs(v[i]-v[j])==2&&e[i][j]){puts("No");return 0;}         }     puts("Yes");     for(int i=1;i<=n;i++)         printf("%c",'a'+v[i]-1);     printf("\n");     return 0; | 
B. Array GCD
题意
给定长为n的数列和两个操作,每个操作用一次
1.移除数列的一个子串,代价是长度*a
2.对于一些数字+1或者-1,每个数字代价为b
求使得数列的gcd大于1的最小代价
题解
由于不能删掉所有的数,那么至少会剩下第一个或最后一个
这两个可能会被修改,枚举2 * 3 = 6种情况,分解质因数后扫一遍数列,取最优值
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #include<map> #include<set> #include<cmath> #include<stack> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define pi acos(-1) #define mod 10000007 #define inf 1000000000 #define ll long long using namespace std; ll read() {     ll x=0,f=1;char ch=getchar();     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}     return x*f; } ll mn; int n; ll a,b; int v[1000005]; ll c[1000005],f[1000005]; void cal(int x) {     ll l=1,r=n,g=0;     for(int i=1;i<=n;i++)     {         if(v[i]%x==1||v[i]%x==x-1)c[i]=b;         else if(v[i]%x==0)c[i]=0;         else c[i]=mn;     }     for(int i=1;i<=n;i++)         f[i]=min(f[i-1]+c[i],mn);     for(int i=1;i<=n;i++)         f[i]=min(f[i-1],f[i]-a*i);     for(int i=n;i;i--)     {         mn=min(mn,f[i]+g+a*i);         g=min(g+c[i],mn);     } } void solve(int t) {     for(int i=2;i<=100000;i++)         if(t%i==0)         {             cal(i);             while(t%i==0)t/=i;         }     if(t!=1)cal(t); } int main() {     n=read();a=read();b=read();     mn=(n-1)*a;     for(int i=1;i<=n;i++)         v[i]=read();     for(int i=-1;i<=1;i++)         solve(i+v[1]),solve(i+v[n]);     cout<<mn<<endl;     return 0; } | 
                                  Subscribe  
                            
                                                                        
                    