2012年 acm-icpc金华现场赛(A,I,J,K)

7 篇文章 0 订阅

I题

求平方和,大水题

J题

一个组合数学题
我用的方法是用两个数组分别存下裤子是某个时是否之前出现过上衣和鞋子, O ( p ) O(p) O(p)

#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}

const int maxn = 2000010;

int n,m,k;
int p;
string a,b;
int x,y;
int mid1[maxn];
int mid2[maxn];
int main(int argc, char const *argv[])
{
    while(cin>>n>>m>>k,n||m||k)
    {
        ll ans = 0;
        cin>>p;
        memset(mid1,0,sizeof mid1);
        memset(mid2,0,sizeof mid2);
         rep(i,0,p)
        {
            cin>>a>>x>>b>>y;
            if(a[0] == 'c')
            {
                if(mid2[y] > 0)
                    ans += k-mid2[y];
                else ans += k;
                mid1[y]++;
            }
            else
            {
                if(mid1[x] > 0)
                    ans += n-mid1[x];
                else ans += n;
                //cout<<"----"<<ans<<endl;
                mid2[x]++;
            }
            // cout<<mid1[y]<<endl;
        }
        ans = n*m*k - ans;
        cout<<ans<<endl;
    }
    return 0;
}

A题

贪心,先考虑两个元素
先1后2: a 1 + a 2 + a 1 ∗ b 2 a_1+a_2+a_1*b_2 a1+a2+a1b2
先2后1: a 1 + a 2 + b 1 ∗ a 2 a_1+a_2+b_1*a_2 a1+a2+b1a2
1排在2前面: a 1 ∗ b 2 &lt; b 1 ∗ a 2 a_1*b_2&lt;b_1*a_2 a1b2<b1a2
事实上,我写过更难的题目,NOIP2012国王游戏,然而训练时却一直记不起来

#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=365*24*60*60;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}

const int maxn = 1e5+10;

ll ans;

struct Node
{
    ll a,b;
} node[maxn];
int n;
bool cmp(Node a,Node b)
{
    return a.b * b.a > b.b * a.a;
}
int main(int argc, char const *argv[])
{
    // cout<<mod<<endl;
    while(cin>>n,n)
    {
        ll ans = 0;
        rep(i,0,n)
        scanf("%lld%lld",&node[i].a,&node[i].b);
        sort(node,node+n,cmp);
        rep(i,0,n)
        {
            ans = ans%mod + ans%mod * node[i].b%mod + node[i].a%mod;
            ans %= mod;
        }
        cout<<ans%mod<<endl;
    }   
    return 0;
}

K题

大模拟,一个很容易想到的简化代码的方法,用0,1,2,3代表方向,然后左转和撞墙都可以进行mod操作

#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}

int n;
const int maxn=1e5+7;
char div1[5];
char div2[5];
int s1,s2,t1,t2;
int k;
int ma[30][30];
struct node
{
    int x,y;
    int di;
    int v;
};
int getdi (char a)
{
    if(a=='S') return 2;
    if(a=='N') return 0;
    if(a=='E') return 1;
    return 3;
}
node tom;
node jerry;
void swapdi(node &a,node &b)
{
    swap(a.di,b.di);
}
bool check(node &a)
{
    if(a.x==0&&a.di==0)  {a.x = 2;return true;}
    if(a.x==n+1&&a.di==2) {a.x -= 2;return true;}
    if(a.y==0&&a.di==3)  {a.y = 2;return true;}
    if(a.y==n+1&&a.di==1) {a.y -= 2;return true;}
    return false;
}
void gonext(node &a)
{

    int t = a.v;
    while(t--)
    {
    
    if(a.di==1) a.y++;
    else if(a.di==2) a.x++;
    else if(a.di==3) --a.y;
    else if(a.di==0) --a.x;
    if(check(a)) a.di=(a.di+2)%4;   
    // if(tom.x==jerry.x&&tom.y==jerry.y) swapdi(tom,jerry);
    
            // if(check(jerry)) jerry.di=(jerry.di+2)%4;
    }
}
int main()
{
    while(cin>>n&&n)
    {
        scanf("%s%d%d",div1,&s1,&t1);
        scanf("%s%d%d",div2,&s2,&t2);
        scanf("%d",&k);
        int t=0;
        tom.v =s1;
        jerry.v = s2;
        tom.x=tom.y=1;
        tom.di=getdi(div1[0]);

        jerry.x=jerry.y=n;
        jerry.di=getdi(div2[0]);

        while(t<k)
        {
            gonext(tom);
            gonext(jerry);
            if(tom.x==jerry.x&&tom.y==jerry.y) swapdi(tom,jerry);
            else
                {
                    if((t+1)%t2==0) jerry.di=(jerry.di+3)%4;
                    if((t+1)%t1==0) tom.di=(tom.di+3)%4;
                }
            // printf("%d %d %d %d\n",tom.x,tom.y,jerry.x,jerry.y);
            ++t;
        }

        printf("%d %d\n",tom.x,tom.y);
        printf("%d %d\n",jerry.x,jerry.y);
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值