主要不是为了写816B和816C的,主要是为了做个记录。
http://codeforces.com/problemset/problem/816/B
http://codeforces.com/problemset/problem/816/C
一次提交,6.25日模拟。
http://codeforces.com/problemset/problem/816/D
十二次提交,7.1日搞定(不容易啊)。
//B题代码
int ans[200050], st[200050], en[200050], c[200050];
int n,k,m;
pair <int, int> p[200050];
int main()
{
cin >> n >> k >> m;
for(int i=0;i<n;i++)
{
int a,b;
cin>>a>>b;
b++;
st[a]++;
en[b]++;
}
int cur = 0;
for(int i = 1; i <= 200000; i++)
{
cur += st[i] - en[i];
if(cur >= k)
c[i] = 1;
}
for(int i = 1; i <= 200001; i++)
ans[i] = ans[i - 1] + c[i - 1];
for(int i=0;i<m;i++)
{
int a,b;
cin>>a>>b;
b++;
cout << ans[b] - ans[a] << endl;
}
return 0;
}
//C题代码
using namespace std;
const int maxn=105;
int n,m,a[maxn][maxn],b[maxn][maxn];
int r[maxn],c[maxn];
int ans=-1,mi;
bool jud1(int t)
{
for (int j=1;j<=m;j++)
{
b[1][j]-=t;
if(b[1][j]<0)
{
return true;
}
}
return false;
}
int jud2(int t)
{
for (int i=2;i<=n;i++)
{
int p=b[i][1]-b[1][1];
if (p<0)
return -1;
t+=p;
bool f=false;
for (int j=1;j<=m;j++)
{
b[i][j]-=p;
if(b[i][j]<0)
{
f=true;
break;
}
}
if (f)
return -1;
}
return t;
}
int jud3(int t)
{
for (int j=1;j<=m;j++)
{
for (int i=2;i<=n;i++)
if (b[i][j]!=b[i-1][j])
return -1;
t+=b[1][j];
}
return t;
}
int main()
{
cin>>n>>m;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
cin>>a[i][j];
for (int t=0;t<=500;t++)
{
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
b[i][j]=a[i][j];
if(jud1(t))
continue;
int t1=jud2(t);
if(t1==-1)
continue;
t1=jud3(t1);
if(t1==-1)
continue;
if (ans==-1 || ans>t1)
{
ans=t1;
mi=t;
}
}
cout<<ans<<endl;
if(ans==-1)
return 0;
int t=mi,x=mi;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
b[i][j]=a[i][j];
for (int j=1;j<=m;j++)
b[1][j]-=t;
r[1]=t;
for (int i=2;i<=n;i++)
{
int p=b[i][1]-b[1][1];
r[i]=p;x+=p;
for (int j=1;j<=m;j++)
b[i][j]-=p;
}
for (int j=1;j<=m;j++)
c[j]=b[1][j];
for (int i=1;i<=n;i++)
for (int j=1;j<=r[i];j++)
cout<<"row "<<i<<endl;
for (int i=1;i<=m;i++)
for (int j=1;j<=c[i];j++)
cout<<"col "<<i<<endl;
return 0;
}
下面就是D啦,题目意思是这样滴,Karen去考试,题目是n个数字,用杨辉三角的方法用加和减运算着n个数,第一个符号为加号,然后跟着减号,然后第二行,以此类推,直到算出最终的一个数。
一开始TLE的方法是这样滴(虽然估计的时间复杂度并没有超时,匪夷又所思),如果n是偶数,先化为奇数,其实这一步可以省去,但假如写个函数的话到后面也挺实用的,化为奇数后特判在不在4以内,如果在直接输出结果,不在就继续往下做。
原本如果暴力的话时间复杂度是O(N^2)的,因为每一层只能消去一个数,无疑是非常慢的,所以我优化了一下,每一层消去四个数,也就是合并5个数,这样速度就提高很多。
这样的确是可以,但可能是因为vector的常数问题,仍然TLE,所以要在一些细节上下功夫(由于不想慢慢改,就重写了一遍)
1.加号减号的转换问题,原本是用两个if来判断正负,实则不用,只要用一个变量每次乘以-1就行了。
2.谁说要用vector了,其实两个数组就足够,而且我们可以折半!原本的n我们不把它化成奇数,把它化成偶数,这样,两边的符号完全相同,只要判断最后的符号即可,然后把两边的x,y运算就好了,所以程序能够更快。
这道题最主要的还是计算,手推公式,加油!