D. Dima and Hares
problem
输入n (1 ≤ n ≤ 3000) a1 a2 ... an. b1, b2, ..., bn. c1, c2, ..., cn.
n只兔子,每只兔子喂一遍,abc分别是旁边两只都饿着一直饿着一直饱着两只都饱着的joy值,按照某种顺序喂,求最大joy和。
think
两边的情况太模糊。。我纠结了很久。。
dp[i][0]表示喂完前i-1只第i只在第i-1只之后喂
dp[i][1]表示喂完前i-1只第i只在第i-1只之前喂
答案就是dp[n+1][0]
code
- int a[N], b[N], c[N], dp[N][2];
-
- int main ()
- {
- int n;
- scanf("%d", &n);
- for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
- for(int i = 1; i <= n; ++i) scanf("%d", &b[i]);
- for(int i = 1; i <= n; ++i) scanf("%d", &c[i]);
- dp[1][0] = -100000;
- for(int i = 1; i <= n; ++i){
- dp[i+1][0] = max(dp[i][0] + b[i], dp[i][1] + a[i]);
- dp[i+1][1] = max(dp[i][0] + c[i], dp[i][1] + b[i]);
- }
- cout<<dp[n+1][0]<<endl;
- return 0;
- }
E. Dima and Kicks
problem
输入n m 和一个n*m的01矩阵,问是否存在“一笔画”,并且中间每笔的长度一样并且大于1
think
先判断是否有
11
11这样的,因为这样不能大于1
还有判断是否联通,还有基数点的个数最多2
code
- int a[1111][1111];
- int vis[1111][1111];
- int ans[1111];
- int dx[] = {0, 0, 1, -1};
- int dy[] = {-1, 1, 0, 0};
- int n, m, amount;
-
- int gcd(int x, int y){
- return (x==0 ? y : gcd(y % x, x));
- }
-
- int cal(int x, int y){
- int ans = 0;
- if(x > 1 && a[x-1][y]) ++ans;
- if(x < n && a[x+1][y]) ++ans;
- if(y > 1 && a[x][y-1]) ++ans;
- if(y < m && a[x][y+1]) ++ans;
- return ans;
- }
-
- bool sq(){
- for(int i = 1; i < n; ++i)
- for(int j = 1; j < m; ++j){
- if(a[i][j]==1 && a[i+1][j]==1 && a[i][j+1]==1 && a[i+1][j+1]==1) return true;
- }
- return false;
- }
-
- int dfs(int i,int j){
- if(i<1 || i>n || j<1 || j>m) return 0;
- if(!a[i][j] || vis[i][j]) return 0;
- vis[i][j]=true;
- return dfs(i+1,j) + dfs(i-1,j) + dfs(i,j+1) + dfs(i,j-1) + 1;
- }
-
- bool ou(){
- memset(vis, 0, sizeof(vis));
- for(int i = 1; i <= n; ++i){
- for(int j = 1; j <= m; ++j){
- if(a[i][j]==1){
- if(dfs(i, j)==amount) return true;
- else return false;
- }
- }
- }
- }
-
- int solve(){
- memset(vis, 0, sizeof(vis));
- memset(ans, 0, sizeof(ans));
- int odd = 0;
- for(int i = 1; i <= n; ++i){
- for(int j = 1; j <= m; ++j){
- if(a[i][j]){
- int num = cal(i, j);
- odd += (num&1);
- if(odd >= 3) return 0;
- if(num == 2 && ((a[i+1][j]==1 && a[i-1][j]==1) || (a[i][j+1]==1 && a[i][j-1]==1))) continue;
- vis[i][j] = 1;
- }
- }
- }
- int gg = 1;
- for(int i = 1; i <= n; i++){
- for(int j = 1; j <= m; ++j) if(vis[i][j]){
- for(int d = 0, k; d < 4; ++d){
- for(k = 1; a[i+dx[d]*k][j+dy[d]*k] && !vis[i+dx[d]*k][j+dy[d]*k]; ++k);
- if(k > 1){
- ans[k] = 1;
- gg = k;
- }
- }
- }
- }
-
- for(int k = max(n, m); k > 1; --k)
- if(ans[k]) gg = gcd(gg, k);
- return gg;
- }
-
- int main(){
- amount = 0;
- scanf("%d%d", &n, &m);
- memset(a, 0, sizeof(a));
- for(int i = 1; i <= n; ++i) for(int j = 1; j <= m; amount += a[i][j], ++j) scanf("%d", &a[i][j]);
- if(sq() || !ou()){
- puts("-1");
- return 0;
- }
- int res = solve();
- if(res < 2) puts("-1");
- else{
- for(int i = 2; i < res; ++i){
- if(res % i == 0) printf("%d ", i);
- }
- printf("%d\n", res);
- }
- return 0;
- }