zoukankan      html  css  js  c++  java
  • COCI 2012/2013 Contest #6

    Problems-PDF

    快读异或没注意优先级我是傻逼。


    BAKA

    小模拟一下就完事了。

    #include<bits/stdc++.h>
    using namespace std;
    map<char,int> p;
    int ans=0;
    int main()
    {
    	p['A']=2,p['B']=2,p['C']=2;
    	p['D']=3,p['E']=3,p['F']=3;
    	p['G']=4,p['H']=4,p['I']=4;
    	p['J']=5,p['K']=5,p['L']=5;
    	p['M']=6,p['N']=6,p['O']=6;
    	p['P']=7,p['Q']=7,p['R']=7,p['S']=7;
    	p['T']=8,p['U']=8,p['V']=8;
    	p['W']=9,p['X']=9,p['Y']=9,p['Z']=9;
    	string a;
    	cin>>a;
    	for(int i=0;i<a.size();i++)
    		ans+=(p[a[i]]+1);
    	printf("%d
    ",ans);
    	return 0;
    }
    

    SUME

    最暴力也是思考起来最简单的办法。

    把所有方程(左下或右上的三角形),得到的和是((n-1)(a_1+a_2...+a_n)),可以计算出((a_1+a_2...+a_n))的值。

    然后对于(a_i),把和它有关的方程加起来,得到(a_i+a_1+a_i+a_2...+a_i+a_{i-1}+a_i+a_{i+1}...+a_i+a_n),即((n-1)a_1+a_2+a_3...+a_n),减去一个((a_1+a_2...a_n)),就可以计算出((n-2)a_i),除以((n-2))即为答案。

    不要问为什么是(O(n^2))的,输入都是(O(n^2))的,时间复杂度啥的就无所谓了(bushi)。

    最后,注意开longlong(血泪的教训)

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    int a[1010][1010];
    inline int read()
    {
    	int x=0,f=1;
    	char ch=getchar();
    	while(ch>'9'||ch<'0')
    	{
    		if(ch=='-')f=-1;
    		ch=getchar();
    	}
    	while(ch<='9'&&ch>='0')
    	{
    		x=(x<<3)+(x<<1)+(ch^48);
    		ch=getchar();
    	}
    	return x*f;
    }
    signed main()
    {
    	int n,c=0;
    	scanf("%lld",&n);
    	if(n==2)
    	{
    		puts("1 1");
    		return 0;
    	}
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			a[i][j]=read();
    	for(int i=2;i<=n;i++)
    		for(int j=1;j<i;j++)
    			c+=a[i][j];
    	c/=(n-1);
    	for(int k=1;k<=n;k++)
    	{
    		int cnt=0,ans=n-1;
    		for(int j=1;j<=n;j++)
    			cnt+=a[k][j];
    		printf("%lld ",(cnt-c)/(n-2));
    	}
    	puts("");
    	return 0;
    } 
    

    DBORI

    首先想到(O(n^2))处理处任意两个元素的和值。

    然后可以考虑用一个数组(n[k])表示(k)是否能够由两个元素相加得到。由于有个位置之前的限制,所以记录(n[k]=i)的意义是,(k)能够由(a[i])和一个 (a[j](1leq jleq i))相加得到。

    由于有正负,所以分段存储就行了。

    处理和判断可以同时进行。

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    int a[20010];
    int f[20010];
    int nz[600010];
    int nf[600010];
    signed main()
    {
    	int n;
    	scanf("%lld",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%lld",&a[i]);
    		for(int j=1;j<=i;j++)
    		{
    			int k=a[i]+a[j];
    			if(k>=0&&!nz[k])nz[k]=i;
    			else if(k<0&&!nf[-k])nf[-k]=i;
    			int p=(a[i]-a[j]>=0)?nz[a[i]-a[j]]:nf[a[j]-a[i]];
    			if(p&&p<i&&j!=i)f[i]=1;
    		}
    	}
    	int ans=0;
    	for(int i=1;i<=n;i++)
    		ans+=f[i];
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    BUREK

    容易发现能切割一个三角形的线就是在三角形横坐标覆盖范围内的或者是纵坐标覆盖范围内的。

    那么容易得到一个三角形横纵坐标的极差,给范围内除端点外的点加一,查询的时候直接输出就可以了。

    发现会超时,于是上个基础数据结构搞一搞就好了。

    #include<bits/stdc++.h>
    using namespace std;
    inline int lowbit(int x)
    {
    	return x&-x;
    }
    int c[2][5000010];
    const int MX=2e6+10;
    const int ADD=1;
    inline void adde(int x,int v,int k)
    {
    	for(int i=x;i<=MX;i+=lowbit(i))
    		c[k][i]+=v;
    }
    inline void add(int x,int y,int v,int k)
    {
    	adde(x,v,k);
    	adde(y+1,-v,k);
    }
    inline int ask(int x,int k)
    {
    	int cnt=0;
    	for(int i=x;i;i-=lowbit(i))
    		cnt+=c[k][i];
    	return cnt;
    }
    inline int read()
    {
    	int x=0,f=1;
    	char ch=getchar();
    	while(ch>'9'||ch<'0')
    	{
    		if(ch=='-')f=-1;
    		ch=getchar();
    	}
    	while(ch<='9'&&ch>='0')
    	{
    		x=(x<<3)+(x<<1)+(ch^48);
    		ch=getchar();
    	}
    	return x*f;
    }
    int a[6];
    int main()
    {
    	int n,m;
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		for(int k=0;k<6;k++)
    		{
    			a[k]=read();
    			a[k]+=ADD;
    		}
    		//1x0y
    		int q=min(min(a[0],a[2]),a[4]),w=max(max(a[0],a[2]),a[4]);
    		int e=min(min(a[1],a[3]),a[5]),r=max(max(a[1],a[3]),a[5]);
    		add(q+1,w-1,1,1);
    		add(e+1,r-1,1,0);
    	}
    	scanf("%d",&m);
    	for(int i=1;i<=m;i++)
    	{
    		string xy,d;
    		cin>>xy>>d;
    		int c;
    		c=read();
    		printf("%d
    ",ask(c+ADD,xy=="x"?1:0));
    	}
    	return 0;
    }
    

    剩下两道题下次丕定补。

  • 相关阅读:
    如何生成随机数
    2017新数组
    JAVA基础
    java基本数据类型
    简易图片自动轮播
    JDK,JRE,JVM
    年月日 日期选择问题
    多选按钮选中进行下一步
    js基本函数和基本方法
    数组简单应用
  • 原文地址:https://www.cnblogs.com/moyujiang/p/13777922.html
Copyright © 2011-2022 走看看