読者です 読者をやめる 読者になる 読者になる

夢追い人

"It takes a dreamer to make a dream come true."―Vincent Willem van Gogh

合宿埋め〜

旅行先で始めました

score

めんどくさい

#include <cstdio>
#include <algorithm>
using namespace std;
struct score {
    int s, r, n;
};
bool comp1(const score& a, const score& b) {
    return a.s>b.s;
}
bool comp2(const score& a, const score& b) {
    return a.n<b.n;
}
score stu[100000];
int main() {
    int n; scanf("%d",&n);
    for (int i=0; i<n; i++) {
        scanf("%d",&stu[i].s);
        stu[i].n=i;
    }
    sort(stu, stu+n, comp1);
    int rank=1, cnt=0, bef=-1;
    for (int i=0; i<n; i++) {
        if (bef!=stu[i].s) {
            bef=stu[i].s;
            rank+=cnt;
            stu[i].r=rank;
            cnt=1;
        } else {
            cnt++;
            stu[i].r=rank;
        }
    }
    sort(stu, stu+n, comp2);
    for (int i=0; i<n; i++) {
        printf("%d\n",stu[i].r);
    }
}

factorial

数学ゲーでカンニングした。
n=p1^x1 * p2^x2 * ... * pm^xm
とあらわせたとき
max(pk*xk)が答えになるというもの。
よく考えたら自明だけれどもこんなの無理げー(数学力つけよう)

#include <cstdio>
#include <algorithm>
using namespace std;
int main() {
    int n; scanf("%d",&n);
    int res, ans=1;
    for (int i=2; i<=n; i++) {
        res=0;
        while (n%i==0) {
            n/=i;
            res+=i;
        }
        ans=max(ans,res);
    }
    printf("%d\n",ans);
}

mall

-1の処理にちょっと手間取りました。
-1をINT_MAXとかにして、もれないように合計をlong longで計算すると、ようするにただの累積和です

#include <cstdio>
#include <climits>
#include <algorithm>
using namespace std;
typedef long long ll;
int field[1005][1005];
ll sum[1005][1005];
int m,n,a,b;
int main() {
    scanf("%d%d%d%d",&m,&n,&a,&b);
    for (int i=1; i<=n; i++) for (int j=1; j<=m; j++) {
        scanf("%d",&field[i][j]);
        if (field[i][j]==-1) field[i][j]=INT_MAX;
    }
    for (int i=1; i<=n; i++) {
        for (int j=1; j<=m; j++) {
            sum[i][j]=field[i][j]+sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1];
        }
    }
    ll res=INT_MAX;
    for (int i=b; i<=n; i++) {
        for (int j=a; j<=m; j++) {
            ll s=sum[i][j]-sum[i-b][j]-sum[i][j-a]+sum[i-b][j-a];
            res=min(res, s);
        }
    }
    printf("%lld\n",res);
}

building

いつやったやつだしwww
最長増加部分列ね

#include <cstdio>
#include <algorithm>
using namespace std;
#define INF 20000
int main() {
	int n; scanf("%d",&n);
	int a[n], dp[n];
	for (int i=0; i<n; i++) scanf("%d",&a[i]);
	fill(dp, dp+n, INF);
	for (int i=0; i<n; i++) {
		*lower_bound(dp,dp+n,a[i])=a[i];
	}
	printf("%d\n",lower_bound(dp,dp+n,INF)-dp);
}

route

dijkstra変形だったけど、90点しか取れなかったので最後カンニングした
ポイントは頂点というより各辺を使うまでの最短を確定させていくといった感じ

#include <cstdio>
#include <cmath>
#include <climits>
#include <map>
#include <vector>
#include <queue>
#include <functional>
#include <algorithm>
using namespace std;
struct edge {
int from,to, cost;
bool flag;
};
struct dg { int x, y; };
typedef pair<int, edge*> P;
vector<edge> G[105];
dg dot[105];
bool isdon(int a, int b, int c) {
    long long ax=dot[a].x-dot[b].x, ay=dot[a].y-dot[b].y;
    long long cx=dot[c].x-dot[b].x, cy=dot[c].y-dot[b].y;
    long long ac=ax*cx+ay*cy;
    if (ac<=0) return true;
    else return false;
}
void dijkstra() {
    priority_queue<P, vector<P>, greater<P> > que;
    for (int i=0; i<G[0].size(); i++) {
        que.push(P(G[0][i].cost,&G[0][i]));
    }
    while (!que.empty()) {
        P p=que.top(); que.pop();
        int dist=p.first;
        edge& e=*p.second;
        if (e.flag) continue;
        e.flag=true;
        if (e.to==1) {
            printf("%d\n",dist);
            return;
        }
        for (int i=0; i<G[e.to].size(); i++) {
            edge& e2=G[e.to][i];
            if (isdon(e.from,e.to,e2.to)) {
                que.push(P(dist+e2.cost,&e2));
            }
        }
    }
    puts("-1");
    return;
}
int main() {
    int n, m; scanf("%d%d",&n,&m);
    for (int i=0; i<n; i++) scanf("%d%d",&dot[i].x,&dot[i].y);
    for (int i=0; i<m; i++) {
        int a,b,c; scanf("%d%d%d",&a,&b,&c);
        G[a-1].push_back((edge){a-1,b-1,c,false});
        G[b-1].push_back((edge){b-1,a-1,c,false});
    }
    dijkstra();
}

anagram

めんどくさーいってダダこねちゃったやつ(´・ω・`)
よくある数学の問題でもあるよね、重複を上手く処理しながら数えます

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
map<char, int> cnt;
ll calc[21];
int main() {
    calc[0]=0;
    calc[1]=1;
    for (int i=2; i<=20; i++) calc[i]=calc[i-1]*i;
    string str; cin>>str;
    for (int i=0; i<str.size(); i++) {
        if (cnt.find(str[i])!=cnt.end()) cnt[str[i]]++;
        else cnt[str[i]]=1;
    }
    ll ans=0;
    int sz=str.size()-1;
    for (int i=0; i<str.size()-1; i++) {
        for (map<char,int>::iterator j=cnt.begin(); j!=cnt.end(); j++) {
            if ((*j).first==str[i]) break;
            cnt[(*j).first]--;
            ll res=0;
            if (cnt[(*j).first]>=0) res+=calc[sz-i];
            for (map<char,int>::iterator it=cnt.begin(); it!=cnt.end(); it++) {
                if ((*it).second>=2) res/=calc[(*it).second];
            }
            ans+=res;
//            printf("%d %lld %c\n",i,res,(*j).first);
            cnt[(*j).first]++;
        }
        cnt[str[i]]--;
    }
    printf("%lld\n",ans+1);
}

まとめ

ふぇ〜〜〜〜
旅行先精進つらー(笑)

広告を非表示にする