比较简单的签到题
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
int T;
ll gcd(ll aa,ll bb){
if(bb)return gcd(bb,aa%bb);
return aa;
}
int main(){
cin>>T;
while(T--){
ll a,b;
cin>>a>>b;
ll gg=gcd(a,b);
ll ag=a/gg,bg=b/gg;
if(bg==1){
cout<<2*a<<endl;
continue;
}
for(ll i=2;;i++){
if(gcd(i*ag,bg)==1){
cout<<i*a<<endl;
break;
}
}
}
return 0;
}
心路历程:k的范围1e5 n方是一定不行的 但是正解就是枚举就好
分析:因为只是中点 所以坐标里面最多只有2×1000 × 2×1000的点 并且题目要求只是出现两次就可以结束
那么最坏的情况这些点全部都出现一次 下一个点一定会出现两次
所以直接暴力枚举就好 这个题的想法不得不说很牛
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int N = 1e6 + 10;
pii a[N];
int main()
{
int t;
scanf("%d",&t);
while (t --)
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
map<pii,int> mp;
int pos1 = -1,pos2 = -1;
for(int i = 1;i <= k;i ++)
scanf("%d%d",&a[i].first,&a[i].second);
for(int i = 1;i <= k;i ++)
for(int j = i + 1;j <= k;j ++)
{
mp[{a[i].first + a[j].first,a[i].second + a[j].second}] ++;
if (mp[{a[i].first + a[j].first,a[i].second + a[j].second}] >= 2)
{
pos1 = i;
pos2 = j;
goto cc;
}
}
cc: if (~pos1)
{
double x = (a[pos1].first + a[pos2].first) * 1.0 / 2.0;
double y = (a[pos1].second + a[pos2].second) * 1.0 / 2.0;
printf("YES %.1lf %.1lf\n",x,y);
}
else puts("NO");
}
return 0;
}
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int mod=1e9+7;
int n;
int main(){
cin>>n;
ll ans=1;
for(int i=1;i<=n;i++){
ll x;scanf("%lld",&x);
ans=ans*(i-x+1)%mod;
}
cout<<ans<<endl;
return 0;
}
首先想到可以缩点 最后剩下一张拓扑图 如果连通区域有多个 那么一定无解
对于一个拓扑序唯一的 一定存在一个解 对于拓扑序不唯一的 也就是每次队内元素>=2 一定是无解的
还有一个特别容易忽略的情况 那就是缩点后的强连通分量的大小为2 也就是有一个点对<a,b> 存在两条边a->b 和b->a
这样任然无法满足
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<math.h>
#include<vector>
#pragma comment(linker,"/STACK:1024000000,1024000000")
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const double eps=1e-6;
const int maxn=100000+10;
const int maxm=200000+10;
const int INF=1361474528;
struct{
int to,w,next;
}edge[maxm];
int head[maxn],tot;
void Init(){
tot=0;
memset(head,-1,sizeof(head));
}
void addedge(int a,int b,int w){
edge[tot].to=b;
edge[tot].w=w;
edge[tot].next=head[a];
head[a]=tot++;
}
int dfn[maxn],low[maxn],scc[maxn],vis[maxn],stk[maxn],top,sccnum,indexx;
void tarjan(int x)
{
if(dfn[x])return ;
dfn[x]=++indexx;
vis[x]=1;
low[x]=dfn[x];
stk[top++]=x;
for(int i=head[x];i!=-1;i=edge[i].next)
{
int to=edge[i].to;
if(!dfn[to]){
tarjan(to);
low[x]=min(low[x],low[to]);
}
else if(vis[to])low[x]=min(low[x],dfn[to]);
}
if(dfn[x]==low[x])
{
sccnum++;
while(1)
{
int now=stk[--top];
scc[now]=sccnum;
vis[now]=0;
if(now==x)break;
}
}
}
void get_scc(int n)
{
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
indexx=0;top=0;sccnum=0;
for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
}
int du[maxn];
vector<int>v[maxn];
queue<int>q;
int num[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
Init();
for(int i=0;i<maxn;i++)v[i].clear(),du[i]=0,num[i]=0;
while(!q.empty())q.pop();
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
addedge(a,b,1);
}
get_scc(n);
for(int i=1;i<=n;i++)
{
num[scc[i]]++;
for(int j=head[i];j!=-1;j=edge[j].next)
{
int to=edge[j].to;
if(scc[i]==scc[to])continue;
du[scc[to]]++;
v[scc[i]].push_back(scc[to]);
}
}
int ok=1;
for(int i=1;i<=sccnum;i++)if(num[i]==2)ok=0;
for(int i=1;i<=sccnum;i++)
{
if(du[i]==0)q.push(i);
}
while(!q.empty())
{
int p=q.front();
q.pop();
if(!q.empty()){ok=0;break;}
for(int to:v[p])
{
du[to]--;
if(du[to]==0)q.push(to);
}
}
if(ok)printf("YES\n");
else printf("NO\n");
}
return 0;
}