/*
Codeforces Round #390 (Div. 2)
時間: 2017/02/16
A. Lesha and array splitting
題意:將集合分成幾個小集合,要求小集合的和不為0.
題解:遍歷過去,一直到不滿足集合並數字非0前生成一個集合
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 110;
int a[N];
int rel[N],rer[N];
int main()
{
int n;
while(~scanf("%d",&n))
{
int flag = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d",&a[i]);
if(a[i])
flag = 1;
}
if(!flag)
puts("NO");
else
{
puts("YES");
int r = 1,l = 1;
int sum = 0;
int k = 0;
while(r <= n)
{
sum += a[r];
if(!sum && a[r])
{
rel[k] = l;
rer[k++] = r-1;
l = r;
}
else
r++;
}
rel[k] = l;
rer[k++] = r-1;
printf("%d\n",k);
for(int i = 0; i < k; i++)
printf("%d %d\n",rel[i],rer[i]);
}
}
return 0;
}
/*
Codeforces Round #390 (Div. 2)
時間: 2017/02/16
B. Ilya and tic-tac-toe game
題意:給你一個4*4的棋盤,誰先連成三子誰贏,‘x’為先手下的棋,‘o’為後手下的棋,‘.’為空,問先手下一步能不贏
題解:將列舉每個空格位置,判斷位置可行性
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 10;
int p[N][N];
bool hefa(int x,int y)
{
if(x >= 0 && x <= 3 && y >= 0 && y <= 3)
return true;
return false;
}
bool pan(int x,int y)
{
if(hefa(x-1,y) && hefa(x-2,y) && p[x-1][y] == 1 && p[x-2][y] == 1)
return true;
if(hefa(x-1,y-1) && hefa(x-2,y-2) && p[x-1][y-1] == 1 && p[x-2][y-2] == 1)
return true;
if(hefa(x+1,y) && hefa(x+2,y) && p[x+1][y] == 1 && p[x+2][y] == 1)
return true;
if(hefa(x+1,y+1) && hefa(x+2,y+2) && p[x+1][y+1] == 1 && p[x+2][y+2] == 1)
return true;
if(hefa(x-1,y-1) && hefa(x+1,y+1) && p[x-1][y-1] == 1 && p[x+1][y+1] == 1)
return true;
if(hefa(x-1,y) && hefa(x+1,y) && p[x-1][y] == 1 && p[x+1][y] == 1)
return true;
if(hefa(x,y-1) && hefa(x,y-2) && p[x][y-1] == 1 && p[x][y-2] == 1)
return true;
if(hefa(x-1,y+1) && hefa(x-2,y+2) && p[x-1][y+1] == 1 && p[x-2][y+2] == 1)
return true;
if(hefa(x,y+1) && hefa(x,y+2) && p[x][y+1] == 1 && p[x][y+2] == 1)
return true;
if(hefa(x+1,y-1) && hefa(x+2,y-2) && p[x+1][y-1] == 1 && p[x+2][y-2] == 1)
return true;
if(hefa(x+1,y-1) && hefa(x-1,y+1) && p[x+1][y-1] == 1 && p[x-1][y+1] == 1)
return true;
if(hefa(x,y-1) && hefa(x,y+1) && p[x][y-1] == 1 && p[x][y+1] == 1)
return true;
return false;
}
int main()
{
char s[N];
while(~scanf("%s",s))
{
int a;
for(int j = 0; j < 4; j++)
{
if(s[j] == 'x')
a = 1;
else if(s[j] == '.')
a = 0;
else
a = 2;
p[0][j] = a;
}
for(int i = 1; i < 4; i++)
{
scanf("%s",s);
for(int j = 0; j < 4; j++)
{
if(s[j] == 'x')
a = 1;
else if(s[j] == '.')
a = 0;
else
a = 2;
p[i][j] = a;
}
}
int flag = 0;
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
//printf("%d ",p[i][j]);
if(!p[i][j] && pan(i,j))
{
flag = 1;
break;
}
}
//puts("");
if(flag)
break;
}
if(flag)
puts("YES");
else
puts("NO");
}
return 0;
}
/*
Codeforces Round #390 (Div. 2)
時間: 2017/02/17
C題 Vladik and chat
題意:給你幾段對話,和幾個說話人的名字,要求得到不可知說話人的名字。
秉承的原則:
1.一個人不可能說兩個連續的話
2.說話的人不能提到自己的名字
題解:
dp[i][j] = 1 代表第i句可能是j人說。
dp2[i][j] = 1 代表考慮前i-1句,第i-1句是j人說。
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
const int N = 150;
map<string,int> mp;
int dp[N][N];
int dp2[N][N];
int res[N];
int flag;
int n,m;
int cal(int id, int limit)
{
int &ret = dp2[id][limit];
if (id > m)
return ret = 1;
if (ret != -1)
return ret;
ret = 0;
for (int i = 1; i <= n; i++)
{
if(dp[id][i] && limit != i)
{
ret = max(ret, cal(id + 1, i));
}
}
return ret;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
mp.clear();
memset(dp,0,sizeof(dp));
memset(dp2,-1,sizeof(dp2));
scanf("%d",&n);
getchar();
string name[N];
for(int i = 0; i < n; i++)
{
cin >> name[i+1];
mp[name[i+1]] = i+1;
}
scanf("%d",&m);
getchar();
char s[N];
string rec[N];
flag = 1;
for(int i = 1; i <= m; i++)
{
gets(s);
int len = strlen(s);
int j;
string a;
for(j = 0; j < len; j++)
{
if(s[j] == ':') break;
a += s[j];
}
int begin = j;
for(int j = begin; j < len; j++)
rec[i] += s[j];
if(a == "?")
{
for(int k = 1; k <= n; k++)
dp[i][k] = 1;
for(j = begin; j < len; j++)
{
if(!isalnum(s[j])) continue;
string b;
int k;
for(k = j; k < len; k++)
{
if(!isalnum(s[k])) break;
b += s[k];
}
j = k;
if(mp[b])
dp[i][mp[b]] = 0;
}
}
else
{
int id = mp[a];
dp[i][id] = 1;
for(j = begin; j < len; j++)
{
if(!isalnum(s[j])) continue;
string b;
int k;
for(k = j; k < len; k++)
{
if(!isalnum(s[k])) break;
b += s[k];
}
j = k;
if(b == a)
{
flag = 0;
break;
}
}
}
}
if(!flag)
puts("Impossible");
else
{
int ans = cal(1,0);
if(!ans)
puts("Impossible");
else
{
int k;
for (int i = 1; i <= n; i++)
{
if (dp2[m + 1][i] == 1)
{
k = i;
break;
}
}
int id = m;
while (1)
{
res[id] = k;
if (id == 1)
break;
for (int i = 1; i <= n; i++)
{
if (k != i&&dp2[id][i] == 1)
{
k = i;
break;
}
}
id--;
}
for (int i = 1; i <= m; i++)
cout << name[res[i]] << rec[i] << endl;
}
}
}
return 0;
}
/*
Codeforces Round #390 (Div. 2)
時間: 2017/02/16
D. Fedor and coupons
題意:給你n個具有範圍的禮券,選擇k個禮券,要求k個禮券交叉包含的範圍最大,輸出範圍大小和選擇的禮券。
題解:要選k個禮券維護最大,我們要使禮券交叉左極限小,右極限大。這樣看來將禮券按左極限排序,然後右極限用優先佇列維護即可。
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 300010;
struct asd
{
int l,r,id;
friend bool operator< (asd n1,asd n2)
{
return n1.r > n2.r;
}
}a[N];
bool cmp(asd n1,asd n2)
{
return n1.l < n2.l;
}
int main()
{
int n,k;
while(~scanf("%d%d",&n,&k))
{
for(int i = 1; i <= n; i++)
{
scanf("%d%d",&a[i].l,&a[i].r);
a[i].id = i;
}
sort(a+1,a+n+1,cmp);
priority_queue<asd> q;
int ans = 0,res = 0;
for(int i = 1; i <= n; i++)
{
asd temp;
if(!q.empty())
temp = q.top();
if(q.size() < k)
q.push(a[i]);
else if(temp.r < a[i].r)
{
q.pop();
q.push(a[i]);
}
if(q.size() == k)
{
temp = q.top();
if(temp.r-a[i].l+1 > ans)
{
ans = temp.r-a[i].l+1;
res = i;
}
}
}
printf("%d\n",ans);
if(ans)
{
int id = 0;
for(int i = 1; i <= res && id < k; i++)
{
if(a[res].l+ans-1 <= a[i].r)
{
printf("%d ",a[i].id);
id++;
}
}
}
else
{
for(int i = 1; i <= k; i++)
printf("%d ",i);
}
puts("");
}
return 0;
}